2016-02-01 2 views
3

Я хочу, чтобы иметь возможность отбрасывать строки из объекта с несколькими индексами данных с использованием нескольких критериев уровня (с логическим И, соединяющим критерии).Отбрасывать многоиндексированные строки DataFrame на основе состояния «AND» между уровнями

Рассмотрим объект панды dataframe определяется по формуле:

import pandas as pd 
df = pd.DataFrame(data = [[1,'x'],[2,'x'],[1,'y'],[2,'y']], 
        index=pd.MultiIndex(levels=[['A','B'],['a','b']], 
             labels=[[0,1,0,1],[0,1,1,0]], 
             names=['idx0','idx1'])) 

print(df) выходов:

  0 1 
idx0 idx1  
A a  1 x 
B b  2 x 
A b  1 y 
B a  2 y 

Я хотел бы исключить строку, в которой 'idx0'=='A'и'idx1'=='a', так что конечный результат:

  0 1 
idx0 idx1  
B b  2 x 
    a  2 y 
A b  1 y 

Мне кажется, что это невозможно сделать с помощью метода df.drop(). А «карусель» путь, который дает правильный результат, чтобы сделать:

df = pd.concat([df.drop(labels='A',level=0),df.drop(labels='a',level=1)]) 
df = df.drop_duplicates() 

Но я полагаю, что должен быть лучший способ ...

ответ

3

Для решения вашего вопроса относительно .drop() - просто передать MultiIndex этикетки в tuple:

df.drop(('A', 'a')) 

      0 1 
idx0 idx1  
B b  2 x 
A b  1 y 
B a  2 y 
1

Вы можете использовать isin метод индекса и принять противоположную что вы с выбором ~:

In [85]: df.index.isin([('A','a')]) 
Out[85]: array([ True, False, False, False], dtype=bool) 

In [86]: df[~df.index.isin([('A','a')])] 
Out[86]: 
      0 1 
idx0 idx1 
B b  2 x 
A b  1 y 
B a  2 y 

Хронометраж:

In [95]: %timeit df.drop(('A','a')) 
1000 loops, best of 3: 1.33 ms per loop 

In [96]: %timeit df[~df.index.isin([('A','a')])] 
1000 loops, best of 3: 457 us per loop 

Так что падение почти в 3 раза медленнее, чем с isin.

Смежные вопросы