Groupby дает мне дополнительный уровень индексов

#python #pandas

#python #панды

Вопрос:

У меня есть фрейм данных, который содержит рейтинги на уровне группы:

        foo  rank
year            
2000    10   340
2000  7010   134
2000  7000   135
2000  6940    83
2000  6840    82
2000  6830    19
2000  6820    81
2000  6800   162
2000  6765   161
2000  7020   136
  

Я написал функцию, которая группирует ранжирование по некоторому произвольному n . Для n=2 этого эквивалентно группированию верхних 50% рангов вместе и нижних 50%:

 def createRankGroups(group, n):
    maxRank = group['rank'].max()
    group['group'] = np.nan
    for i in range(1, n   1):
        upperRankBoundary = maxRank / n * i
        idx = (group['rank'] <= upperRankBoundary) amp; group.group.isnull()
        group.loc[idx, 'group'] = i
    return group['group']
  

Проблема в том, что когда я использую apply эту функцию, я получаю обратно ненужный уровень индексов, что разрушает слияние.

 df['group'] = df.groupby(level=0).apply(lambda x: createRankGroups(x, 2))
Exception: cannot handle a non-unique multi-index!
  

И вот почему:

 In[42]: df.groupby(level=0).apply(lambda x: createRankGroups(x, 2)).head()
Out[42]: 
year  year
2000  2000    2
      2000    1
      2000    1
      2000    1
      2000    1
  

Я подумал, что, возможно, это было вызвано тем, что индексы были неуникальными (поскольку я не проходил мимо foo , поэтому я тоже попробовал это:

 In[43]: df = df.reset_index().set_index(['year', 'foo'])
In[44]: df.groupby(level=0).apply(lambda x: createRankGroups(x, 2)).head()
Out[44]: 
year  year  foo 
2000  2000  10      2
            7010    1
            7000    1
            6940    1
            6840    1
  

Наконец, также принудительная сортировка по индексу by df.sort_index(level=0, inplace=True) не решила проблему. Что я могу сделать?

Комментарии:

1. Я знаю, что мог бы просто .reset_index(level=0, drop=True) , но я ищу причину, по которой это не работает (и как правильно это сделать)

2. Но я получаю a DF в широком формате с обоими index column именами и, соответствующими 2000 году, после выполнения df.groupby(level=0).apply(lambda x: createRankGroups(x, 2)) , а не в длинном формате, как у вас?