Pandas MultiIndex: выбрать столбец, зная только второй индекс?
Я работаю со следующим DataFrame:
age height weight shoe_size
0 8.0 6.0 2.0 1.0
1 8.0 NaN 2.0 1.0
2 6.0 1.0 4.0 NaN
3 5.0 1.0 NaN 0.0
4 5.0 NaN 1.0 NaN
5 3.0 0.0 1.0 0.0
Я добавил еще один заголовок к df следующим образом:
zipped = list(zip(df.columns, ["RHS", "height", "weight", "shoe_size"]))
df.columns = pd.MultiIndex.from_tuples(zipped)
Итак, это новый DataFrame:
age height weight shoe_size
RHS height weight shoe_size
0 8.0 6.0 2.0 1.0
1 8.0 NaN 2.0 1.0
2 6.0 1.0 4.0 NaN
3 5.0 1.0 NaN 0.0
4 5.0 NaN 1.0 NaN
5 3.0 0.0 1.0 0.0
Теперь я знаю, как выбрать первый столбец, используя соответствующий кортеж ("age", "RHS")
:
df[("age", "RHS")]
но мне было интересно, как это сделать, используя только второй индекс "RHS". В идеале что-то вроде:
df[(any, "RHS")]
2 ответа
Решение
Вы передаете slice(None)
в качестве первого аргумента .loc
при условии, что вы сначала сортируете столбцы, используя df.sort_index
:
In [325]: df.sort_index(1).loc[:, (slice(None), 'RHS')]
Out[325]:
age
RHS
0 8.0
1 8.0
2 6.0
3 5.0
4 5.0
5 3.0
Вы также можете использовать pd.IndexSlice
с df.loc
:
In [332]: idx = pd.IndexSlice
In [333]: df.sort_index(1).loc[:, idx[:, 'RHS']]
Out[333]:
age
RHS
0 8.0
1 8.0
2 6.0
3 5.0
4 5.0
5 3.0
С слайсером вам не нужно явно передавать slice(None)
так как IndexSlice
делает это для вас.
Если вы не сортируете свои столбцы, вы получите:
UnsortedIndexError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (2), lexsort depth (0)'
Если у вас есть несколько RHS
столбцы на втором уровне, все эти столбцы возвращаются.
Вы могли бы использовать get_level_values
In [700]: df.loc[:, df.columns.get_level_values(1) == 'RHS']
Out[700]:
age
RHS
0 8.0
1 8.0
2 6.0
3 5.0
4 5.0
5 3.0