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
Другие вопросы по тегам