Панды: условный выбор с использованием .loc с MultiIndex - PullRequest
0 голосов
/ 26 июня 2018

Я прочитал документ Расширенное индексирование с иерархическим индексом , где объясняется использование .loc для MultiIndex.Также этот поток: Использование .loc с MultiIndex в пандах?

Тем не менее я не вижу, как выбрать строки, где (first index == some value) or (second index == some value)

Пример:

import pandas as pd

index = pd.MultiIndex.from_arrays([['a', 'a', 'a', 'b', 'b', 'b'],
                                  ['a', 'b', 'c', 'a', 'b', 'c']],
                                  names=['i0', 'i1'])
df = pd.DataFrame({'x': [1,2,3,4,5,6], 'y': [6,5,4,3,2,1]}, index=index)

Это фрейм данных:

       x  y
i0 i1      
a  a   1  6
   b   2  5
   c   3  4
b  a   4  3
   b   5  2
   c   6  1

Как получить строки, где i0 == 'b' or i1 == 'b'?

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1

Ответы [ 3 ]

0 голосов
/ 26 июня 2018

Использование get_level_values()

>>> mask = (df.index.get_level_values(0)=='b') | (df.index.get_level_values(1)=='b') 
>>> df[mask]  # same as df.loc[mask]


        x   y
i0  i1      
a   b   2   5
b   a   4   3
    b   5   2
    c   6   1
0 голосов
/ 28 ноября 2018

Я думаю, что более простой ответ - использовать функцию DataFrame.query, которая позволяет запрашивать мультииндекс по имени следующим образом:

import pandas as pd
import numpy as np

index = pd.MultiIndex.from_arrays([list("aaabbb"),
                                  list("abcabc")],
                                  names=['i0', 'i1'])
df = pd.DataFrame({'x': [1, 2, 3, 4, 5, 6], 'y': [6, 5, 4, 3, 2, 1]}, index=index)


df.query('i0 == "b" | i1 == "b"')

возвращает:

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1
0 голосов
/ 26 июня 2018

Это может быть возможно при некоторых логических условиях в столбцах индекса i0 и i1 без указания .loc.Однако для меня использование .iloc кажется более простым:

Вы можете получить индекс iloc через pd.MultiIndex.get_locs.

import pandas as pd
import numpy as np

index = pd.MultiIndex.from_arrays([list("aaabbb"),
                                  list("abcabc")],
                                  names=['i0', 'i1'])
df = pd.DataFrame({'x': [1, 2, 3, 4, 5, 6], 'y': [6, 5, 4, 3, 2, 1]}, index=index)

idx0 = index.get_locs(['b', slice(None)])  # i0 == 'b' => [3, 4, 5]
idx1 = index.get_locs([slice(None), 'b'])  # i1 == 'b' => [1, 4]
idx = np.union1d(idx0, idx1)

print(df.iloc[idx])

даст

       x  y
i0 i1      
a  b   2  5
b  a   4  3
   b   5  2
   c   6  1

Примечание: slice(None) означает то же, что и [:] в разрезании индекса.

...