Фильтр MultiIndex со строками запроса - PullRequest
1 голос
/ 08 февраля 2020

У меня довольно большой DataFrame, скажем 600 индексов, и я хочу использовать критерии фильтра для создания уменьшенной версии DataFrame, где критерии верны. Из проведенного мною исследования хорошо работает фильтрация, когда вы применяете выражения к данным и уже знаете индекс, с которым работаете. Однако я хочу применить критерии фильтрации к индексу. См. Пример ниже.

MultiIndex выделен жирным шрифтом, имена MultiIndex: itali c.

enter image description here

Я бы хотел примените следующие критерии (или что-то в этом роде) следующим образом:

df = df[MultiIndex.query('base == 115 & Al.isin(stn)')]

Затем, возможно, сделайте что-то вроде этого:

df = df.transpose()[MultiIndex.query('Fault.isin(cont)')].transpose

В результате:

enter image description here

Я думаю, что в основном я пытаюсь создать логический список для маскировки MultiIndex. Если есть быстрый способ применить запрос pandas к 2d списку? это было бы приемлемо. На данный момент кажется, что есть возможность взять MultiIndex, преобразовать его в DataFrame, а затем я могу применить фильтрацию, как я хочу получить массив TF. Я обеспокоен тем, что это будет медленно, хотя.

Ответы [ 2 ]

1 голос
/ 09 февраля 2020

Если то, что вам нужно, использует изящный синтаксис df.query() для нарезки ваших данных, то вам лучше «отменить» ваш DataFrame, превратив все индексы и метки столбцов в обычные поля.

Вы можете создать «unpivot» DataFrame с:

df_unpivot = df.stack(level=[0, 1]).rename('value').reset_index()

, который создаст DataFrame, который выглядит следующим образом:

  season cont  stn   base value
0 Summer Fault Alpha  115   1.0
1 Summer Fault Beta   115   0.8
2 Summer Fault Gamma  230   0.7
3 Summer Trip  Alpha  115   1.2
4 Summer Trip  Beta   115   0.9
...

К которому вы затем можете запросить:

df_unpivot.query(
    'cont.str.contains("Fault") and '
    'stn.str.contains("Al") and '
    'base == 115'
)

Что дает:

  season cont  stn   base value
0 Summer Fault Alpha  115   1.0
6 Winter Fault Alpha  115   0.7

Какие два значения вы ожидали.

1 голос
/ 08 февраля 2020

Как вы заметили, индексы не подходят для запросов с использованием выражений фильтра. Есть df.filter(), но на MultiIndex он не очень хорошо работает.

Вы все равно можете отфильтровать значения MultiIndex как повторяющиеся из Python кортежей, а затем использовать .loc для доступа к отфильтрованным Результаты.

Это работает:

rows = [(season, cont)
        for (season, cont) in df.index
        if 'Fault' in cont]
cols = [(stn, base)
        for (stn, base) in df.columns
        if base == 115 and 'Al' in stn]
df.loc[rows, cols]
...