Выберите строки в pandas MultiIndex DataFrame

Каковы наиболее распространенные способы выбора / фильтрации строк фрейм данных, индекс которого является MultiIndex?

  • Нарезка на основе одного значения / метки
  • Нарезка на основе нескольких этикеток с одного или нескольких уровней
  • Фильтрация по логическим условиям и выражениям
  • Какие методы применимы в каких обстоятельствах

Предположения для простоты:

  1. входной фрейм данных не имеет повторяющихся ключей индекса
  2. Фреймворк входных данных ниже имеет только два уровня. (Большинство решений, показанных здесь, обобщаются до N уровней)

Пример ввода:

mux = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    list('tuvwtuvwtuvwtuvw')
], names=['one', 'two'])

df = pd.DataFrame({'col': np.arange(len(mux))}, mux)

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    u      5
    v      6
    w      7
    t      8
c   u      9
    v     10
d   w     11
    t     12
    u     13
    v     14
    w     15

Вопрос 1: выбор одного предмета

Как выбрать строки со знаком «а» на уровне «один»?

         col
one two     
a   t      0
    u      1
    v      2
    w      3

Кроме того, как я могу сбросить уровень «один» в выводе?

     col
two     
t      0
u      1
v      2
w      3

Вопрос 1b
Как нарезать все строки со значением «t» на уровне «два»?

         col
one two     
a   t      0
b   t      4
    t      8
d   t     12

Вопрос 2: Выбор нескольких значений на уровне

Как выбрать строки, соответствующие элементам «b» и «d» на уровне «один»?

         col
one two     
b   t      4
    u      5
    v      6
    w      7
    t      8
d   w     11
    t     12
    u     13
    v     14
    w     15

Вопрос 2b
Как мне получить все значения, соответствующие «t» и «w» на уровне «два»?

         col
one two     
a   t      0
    w      3
b   t      4
    w      7
    t      8
d   w     11
    t     12
    w     15

Вопрос 3: Нарезка одинарного поперечного сечения (x, y)

Как мне получить поперечное сечение, то есть одну строку, имеющую определенные значения для индекса из df? В частности, как мне получить поперечное сечение ('c', 'u'), заданное

         col
one two     
c   u      9

Вопрос 4: Нарезка нескольких поперечных сечений [(a, b), (c, d), ...]

Как выбрать две строки, соответствующие ('c', 'u') и ('a', 'w')?

         col
one two     
c   u      9
a   w      3

Вопрос 5: по одному предмету на каждый уровень

Как я могу получить все строки, соответствующие «a» на уровне «один» или «t» на уровне «два»?

         col
one two     
a   t      0
    u      1
    v      2
    w      3
b   t      4
    t      8
d   t     12

Вопрос 6: произвольная нарезка

Как я могу разрезать определенные поперечные сечения? Для «a» и «b» я хотел бы выбрать все строки с подуровнем «u» и «v», а для «d» я хотел бы выбрать строки с подуровнем «w».

         col
one two     
a   u      1
    v      2
b   u      5
    v      6
d   w     11
    w     15

Question 7 will use a unique setup consisting of a numeric level:

np.random.seed(0)
mux2 = pd.MultiIndex.from_arrays([
    list('aaaabbbbbccddddd'),
    np.random.choice(10, size=16)
], names=['one', 'two'])

df2 = pd.DataFrame({'col': np.arange(len(mux2))}, mux2)

         col
one two     
a   5      0
    0      1
    3      2
    3      3
b   7      4
    9      5
    3      6
    5      7
    2      8
c   4      9
    7     10
d   6     11
    8     12
    8     13
    1     14
    6     15

Вопрос 7: Фильтрация по числовому неравенству на отдельных уровнях мультииндекса

Как получить все строки, в которых значения на уровне «два» больше 5?

         col
one two     
b   7      4
    9      5
c   7     10
d   6     11
    8     12
    8     13
    6     15

Примечание. В этом посте нет расскажет, как создавать мультииндексы, как выполнять над ними операции присваивания, или какие-либо обсуждения, связанные с производительностью (это отдельные темы в другой раз).

Похоже, отличный случай для dfsql df.sql (<SQL select statement>) github.com/mindsdb/dfsqlmedium.com/riselab/…

Jorge Torres 20.04.2021 08:37
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
235
1
76 718
2

Ответы 2

Недавно я столкнулся со случаем использования, когда у меня был трехуровневый мультииндексный фрейм данных, в котором я не мог заставить ни одно из вышеперечисленных решений дать результаты, которые я искал. Вполне возможно, что приведенные выше решения, конечно, работают для моего варианта использования, и я попробовал несколько, однако мне не удалось заставить их работать в то время, которое у меня было.

Я далек от эксперта, но наткнулся на решение, которого не было в приведенных выше исчерпывающих ответах. Я не даю никаких гарантий, что решения в любом случае оптимальны.

Это другой способ получить результат, немного отличный от вопроса № 6 выше. (и, вероятно, другие вопросы)

В частности, я искал:

  1. Способ выбора двух + значений из одного уровня индекса и одного значения из другого уровня индекса, и
  2. Способ оставить значения индекса из предыдущей операции в выводе фрейма данных.

Как обезьяний гаечный ключ в шестернях (однако полностью поправимый):

  1. Индексы были безымянными.

На фрейме данных игрушки ниже:

    index = pd.MultiIndex.from_product([['a','b'],
                               ['stock1','stock2','stock3'],
                               ['price','volume','velocity']])

    df = pd.DataFrame([1,2,3,4,5,6,7,8,9,
                      10,11,12,13,14,15,16,17,18], 
                       index)

                        0
    a stock1 price      1
             volume     2
             velocity   3
      stock2 price      4
             volume     5
             velocity   6
      stock3 price      7
             volume     8
             velocity   9
    b stock1 price     10
             volume    11
             velocity  12
      stock2 price     13
             volume    14
             velocity  15
      stock3 price     16
             volume    17
             velocity  18

Конечно, с помощью приведенных ниже работ:

    df.xs(('stock1', 'velocity'), level=(1,2))

        0
    a   3
    b  12

Но мне нужен был другой результат, поэтому мой метод получения этого результата был следующим:

   df.iloc[df.index.isin(['stock1'], level=1) & 
           df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
    b stock1 velocity  12

И если бы я хотел два + значения с одного уровня и одно (или 2+) значение с другого уровня:

    df.iloc[df.index.isin(['stock1','stock3'], level=1) & 
            df.index.isin(['velocity'], level=2)] 

                        0
    a stock1 velocity   3
      stock3 velocity   9
    b stock1 velocity  12
      stock3 velocity  18

Вышеупомянутый метод, вероятно, немного неуклюж, однако я обнаружил, что он удовлетворяет мои потребности и, как бонус, мне было легче понять и прочитать.

Хорошо, я не знал об аргументе level против Index.isin!

cs95 15.05.2020 11:05

Также метод xs вызывает ошибку, если ничего не найдено, в отличие от isin, которые возвращают пустой список.

ipap 08.02.2021 15:51

Похоже, отличный случай для dfsql

df.sql(<SQL select statement>)

https://github.com/mindsdb/dfsql

Полная статья об этом здесь:

https://medium.com/riselab/why-every-data-scientist-using-pandas-needs-modin-bringing-sql-to-dataframes-3b216b29a7c0

Не предоставляйте только ссылки. Пожалуйста, добавьте несколько примеров. Добавьте решения к соответствующим подвопросам.

buhtz 15.09.2021 15:40

Другие вопросы по теме