Как я могу вернуть несколько уровней / групп значений из мультииндексного фрейма данных? - PullRequest
4 голосов
/ 31 октября 2019

Вот мой мультииндексный фрейм данных:

# Index Levels
outside = ['G1','G1','G1','G2','G2','G2']
inside = [1,2,3,1,2,3]
hier_index = list(zip(outside,inside))
hier_index = pd.MultiIndex.from_tuples(hier_index)
df = pd.DataFrame(np.random.randn(6,2),index=hier_index,columns=['A','B'])
df.index.names = ['Group','Num']
df

Фрейм данных выглядит следующим образом:

                  A           B
Group   Num     
G1      1     0.147027  -0.479448
        2     0.558769   1.024810
        3    -0.925874   1.862864
G2      1    -1.133817   0.610478
        2     0.386030   2.084019
        3    -0.376519   0.230336

Чего я хочу добиться, это вернуть значения в Group G1 и G2, Num 1 и 3, что выглядит следующим образом:

G1     1     0.147027   -0.479448
       3    -0.925874    1.862864
G2     1    -1.133817    0.610478
       3    -0.376519    0.230336

Я пробовал

df.loc[['G1','G2']].loc[[1,3]]

, но ничего не показывает.

Затем я попытался

df.xs([['G1','G2'],[1,3]]) 

, но он возвращает

TypeError: '([' G1 ',' G2 '], [1, 3])'является недействительным ключом.

Можно ли как-нибудь заставить его вернуть значения в Group G1 и G2, Num 1 и 3?

Ответы [ 3 ]

4 голосов
/ 31 октября 2019

В качестве альтернативы .loc вы также можете использовать query следующим образом:

df.query('Group in ["G1", "G2"] and Num in [1, 3]')

, который также возвращает:

                  A         B
Group Num                    
G1    1   -1.749477 -0.276759
      3    0.888542 -0.656236
G2    1    0.757631 -1.091000
      3   -1.203232  1.702107

Есливам нравится, что вы также можете использовать параметры в запросах, используя @, что может пригодиться, если у вас длинные списки:

num_sel = [1, 3]
df.query('Group in ["G1", "G2"] and Num in @num_sel')

, дающие тот же вывод.

Вы также можете легкодобавить дополнительные ограничения на записи столбца, например, что значения в A должны быть больше, чем 0:

df.query('Group in ["G1", "G2"] and Num in [1, 3] and A > 0')

, что возвращает

                  A         B
Group Num                    
G1    3    0.888542 -0.656236
G2    1    0.757631 -1.091000
4 голосов
/ 31 октября 2019

Используйте DataFrame.loc со списками:

df1 = df.loc[(['G1','G2'], [1,3]), :]
print (df1)
                  A         B
Group Num                    
G1    1    2.165594  0.466762
      3    0.451996  0.125071
G2    1    2.783947  0.176145
      3    0.169508  0.071441

Или используйте слайсеры :

idx = pd.IndexSlice
df1 = df.loc[idx[['G1','G2'], [1,3]], :]
print (df1)
                  A         B
Group Num                    
G1    1    0.617367 -1.010116
      3   -0.990257 -1.262942
G2    1    1.336134 -0.198787
      3   -0.310426  1.063520
1 голос
/ 31 октября 2019

Метод индексации .loc, равный pandas, принимает уровень каждого индекса в качестве аргумента:

df.loc[['G1','G2'], [1,3],:]

Если у вашего фрейма данных есть 2 индекса и 1 уровень столбцов, метод .locбудет принимать 3 аргумента, по одному на каждый уровень индекса и один для столбцов.

Более подробную информацию вы можете получить, обратившись к документации .

...