2017-02-21 6 views
0

Я принял dataframe (с начальным индексом 0 ... 9999) и распределяли по годам, как, например:Пандас индексация ведет себя неожиданно: DF [df.index [0]] => KeyError

requests_df = {year : df[df['req_year'] == year] for year in df['req_year'].unique()} 

As каждый обычный, каждый подкадр сохраняет свой собственный индексный порядок. Затем, при попытке индексировать на одном из этих изолированных кадров (df_yr = requests_df[2015]) я получаю это действительно неожиданное поведение:

for idx in df_year.index: 
     qty = frame[idx]['qty_tickets'] 

причины:

KeyError         Traceback (most recent call last) 
/home/user/ve/ml/lib/python3.5/site-packages/pandas/indexes/base.py in get_loc(self, key, method, tolerance) 
    2133    try: 
-> 2134     return self._engine.get_loc(key) 
    2135    except KeyError: 

pandas/index.pyx in pandas.index.IndexEngine.get_loc (pandas/index.c:4433)() 

pandas/index.pyx in pandas.index.IndexEngine.get_loc (pandas/index.c:4279)() 

pandas/src/hashtable_class_helper.pxi in pandas.hashtable.PyObjectHashTable.get_item (pandas/hashtable.c:13742)() 

pandas/src/hashtable_class_helper.pxi in pandas.hashtable.PyObjectHashTable.get_item (pandas/hashtable.c:13696)() 

KeyError: 8666 

мышления я goofed итератора, я попытался простой случай :

df_yr[df_yr.index[0]]

KeyError 

ват.

8666, безусловно, значение индекса для первого ряда:

Int64Index([8666, 8667, 8668, 8669, 8670, 8671, 8672, 8673, 8674, 8675, 
      ... 
      9830, 9831, 9832, 9833, 9834, 9835, 9836, 9837, 9838, 9839], 
      dtype='int64', length=1174) 

Индексация с помощью LOC,

outframe.loc[8666] 

который я, хотя опирается на ценности df.index, работает отлично. Ват.

df.ix также работает, что не слишком удивительно, так как она имеет встроенные резервные объявления в.

Я индексируется с помощью манипуляций df.index десятки раз без каких-либо проблем. Что дает?

+3

Попробуйте изменить 'qty = frame [idx] ['qty_tickets']' to 'qty = frame.loc [idx, 'qty_tickets'] ' – jezrael

+1

' df [i] 'по умолчанию индексирует столбцы на основе меток. Оба 'df.loc [i]' и 'df.ix [i]' выполняют индексирование строк. –

+0

@IgorRaush ты показал мне ошибку моих путей! Я предположил, что, поскольку будут выполняться такие фрагменты, как 'df [2: 4]', и я настолько привык к маскировке ('df [df ['foo'] == 'bar]' stuff), что я забыл эту простую строку индексирование завершается с ошибкой после того, как df уже замаскирован. Не возражаете ли вы опубликовать это как ответ? – DeusXMachina

ответ

1

В целом, df[index] будет выполнять с индексом на основе меток на основе меток. Как вы заметили, исключение составляют

  • df[slice] будет порезать строки
  • df[boolean_mask] будет выбрать подмножество строк на основе маски

За исключением этих двух исключений, не существует эффективный способ устранения неоднозначности df[row_label] и df[col_label], поэтому Pandas использует последнюю интерпретацию, поскольку она более совместима со «словарноподобными» кадрами данных. Ваш эксперимент с df_yr[df_yr.index[0]] вызвал ошибку, потому что вы пытаетесь использовать метку индекса строки, где ожидается метка индекса столбца.

Вместо этого следует использовать многоосевых этикетки на основе индексации, для которого синтаксис

df.loc[row_indexer, col_indexer] 

, где col_indexer является необязательным. df.loc[df.index[0]] должен работать нормально. В разбитой части кода используйте

frame.loc[idx, 'qty_tickets'] 

(это также noted by jezrael in the comments).