2016-08-07 9 views
1

Почему при разрезании мультииндексной части данных вы можете избежать простейшего синтаксиса, если вы нарезаете индекс уровня 0? Вот пример dataframe:Почему pandas мультииндексная резка данных выглядит непоследовательной?

  hi 
a b c  
1 foo baz 0 
     can 1 
    bar baz 2 
     can 3 
2 foo baz 4 
     can 5 
    bar baz 6 
     can 7 
3 foo baz 8 
     can 9 
    bar baz 10 
     can 11 

Эти работы:

df.loc[1, 'foo', :] 
df.loc[1, :, 'can'] 

Хотя это не:

df.loc[:, 'foo', 'can'] 

Заставляя меня использовать один из них вместо:

df.loc[(slice(None), 'foo', 'can'), :] 
df.loc[pd.IndexSlice[:, 'foo', 'can'], :] 

Ниже приведены те же примеры, но с большим количеством л:

In [1]: import pandas as pd 
import numpy as np 

ix = pd.MultiIndex.from_product([[1, 2, 3], ['foo', 'bar'], ['baz', 'can']], names=['a', 'b', 'c']) 
data = np.arange(len(ix)) 
df = pd.DataFrame(data, index=ix, columns=['hi']) 
print df 

      hi 
a b c  
1 foo baz 0 
     can 1 
    bar baz 2 
     can 3 
2 foo baz 4 
     can 5 
    bar baz 6 
     can 7 
3 foo baz 8 
     can 9 
    bar baz 10 
     can 11 

In [2]: df.sort_index(inplace=True) 
print df.loc[1, 'foo', :] 

      hi 
a b c  
1 foo baz 0 
     can 1 

In [3]: print df.loc[1, :, 'can'] 

      hi 
a b c  
1 bar can 3 
    foo can 1 

In [4]: print df.loc[:, 'foo', 'can'] 

KeyError: 'the label [foo] is not in the [columns]' 

In [5]: print df.loc[(slice(None), 'foo', 'can'), :] 

      hi 
a b c  
1 foo can 1 
2 foo can 5 
3 foo can 9 

In [6]: print df.loc[pd.IndexSlice[:, 'foo', 'can'], :] 

      hi 
a b c  
1 foo can 1 
2 foo can 5 
3 foo can 9 

ответ

1

Все три примера технически неоднозначным, это только в первых двух, pandas угадывает ваши намерения правильно. Поскольку нарезка строк, выбор столбцов (т. Е. df.loc[:, columns] - распространенная идиома, кажется, что вывод выглядит таким образом.

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

idx = pd.IndexSlice 
df.loc[idx[1, 'foo'], :] 
df.loc[idx[1, :, 'can'], :] 
df.loc[idx[:, 'foo', 'can'], :] 
+0

Почему 'df.loc [:, столбцы]' общий идиома, когда 'ДФ [столбцы]', кажется, сделать то же самое? Я, наверное, не хватает какой-то нюанс. – MarredCheese

+0

это, как правило, делает то же самое ... за исключением случаев, когда это не связано с резервными ошибками. В github есть проблема, которая перечисляет все возможности - https://github.com/pydata/pandas/issues/9595 - как отмечено там, это немного беспорядка, в этот момент прежде всего для обратной совместимости. – chrisb

+0

О, хорошо. Благодаря! – MarredCheese

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