2015-03-10 1 views
3

В Pandas, что является хорошим способом выбора наборов произвольных строк в мультииндексе?Как уйти с многомерным индексом в пандах

df = pd.DataFrame(columns=['A', 'B', 'C']) 
df['A'] = ['a', 'a', 'b', 'b'] 
df['B'] = [1,2,3,4] 
df['C'] = [1,2,3,4] 

the_indices_we_want = df.ix[[0,3],['A','B']] 
df = df.set_index(['A', 'B']) #Create a multiindex 

df.ix[the_indices_we_want] #ValueError: Cannot index with multidimensional key 

df.ix[[tuple(x) for x in the_indices_we_want.values]] 

Эта последняя строка - ответ, но он чувствует неуклюжий ответ; они даже не могут быть списками, они должны быть кортежами. Он также включает в себя создание нового объекта для индексирования. Я нахожусь в ситуации, когда я пытаюсь сделать поиск на мультииндексных dataframe, с индексами от другого dataframe:

data_we_want = dataframe_with_the_data.ix[dataframe_with_the_indices[['Index1','Index2']]] 

Прямо сейчас, похоже, мне нужно написать так:

data_we_want = dataframe_with_the_data.ix[[tuple(x) for x in dataframe_with_the_indices[['Index1','Index2']].values]] 

Это работоспособно, но если есть много строк (т. Е. Сотни миллионов желаемых индексов), то генерация этого списка кортежей становится довольно сложной. Любые решения?


Редактировать: Решение @joris работает, но нет, если индексы являются всеми числами. Пример, где индексы являются все целые числа:

df = pd.DataFrame(columns=['A', 'B', 'C']) 
df['A'] = ['a', 'a', 'b', 'b'] 
df['B'] = [1,2,3,4] 
df['C'] = [1,2,3,4] 

the_indices_we_want = df.ix[[0,3],['B','C']] 
df = df.set_index(['B', 'C']) 

df.ix[pd.Index(the_indices_we_want)] #ValueError: Cannot index with multidimensional key 

df.ix[pd.Index(the_indices_we_want.astype('object'))] #Works, though feels clunky. 

ответ

3

Вы действительно можете не индексировать с DataFrame напрямую, но если преобразовать его в объект Index, он делает правильные вещи (строка в DataFrame будет рассматриваться как один с несколькими индексами):

In [43]: pd.Index(the_indices_we_want) 
Out[43]: Index([(u'a', 1), (u'b', 4)], dtype='object') 

In [44]: df.ix[pd.Index(the_indices_we_want)] 
Out[44]: 
    C 
A B 
a 1 1 
b 4 4 

In [45]: df.ix[[tuple(x) for x in the_indices_we_want.values]] 
Out[45]: 
    C 
A B 
a 1 1 
b 4 4 

Это несколько чище. И с некоторыми быстрыми тестами он кажется немного быстрее (но не так много, всего 2 раза)

+0

Спасибо! Это работает для этого случая, но, похоже, не работает, если индексы являются целыми числами. См. Править выше. – jeffalstott

0

В более новых версиях pandas вы можете просто использовать .iloc для индексации строк.

df = pd.DataFrame(columns=['A', 'B', 'C']) 
df['A'] = ['a', 'a', 'b', 'b'] 
df['B'] = [1,2,3,4] 
df['C'] = [1,2,3,4] 
df.iloc[[0, 3]][['A', 'B']] 

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

  • Нет связанных вопросов^_^