DataFrame: N самых больших значений индексов (от уровня = 1) до n столбцов - PullRequest
0 голосов
/ 16 мая 2018

Я пытаюсь преобразовать такой df:

df = pd.DataFrame({'A': ['A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2'],
      'B': ['B1', 'B1', 'B2', 'B2', 'B3', 'B3', 'B4', 'B5', 'B6', 'B7', 'B7', 'B8', 'B8']})

enter image description here

, взяв n (здесь 2) самых больших индексов (по количеству B) до:

enter image description here

Мой способ сделать это:

df = df.groupby(['A', 'B'])['A'].count()
df = df.groupby(level=0).nlargest(2).reset_index(level=0, drop=True)

что дает мне (что близко к тому, что мне нужно):

enter image description here

Теперь единственные известные мне методы преобразования MultiIndex:

df.reset_index(level=1)
df.unstack()

Но они не даютмне то, что я ищу.Есть ли какой-либо метод dataframe, который сделает это для меня, или мне нужно сделать это с apply.Один из способов сделать это - перебрать каждую пару: df.index.get_level_values(level=1) и поместить ее в новый df из 2 столбцов.Но это сломается. Если один index.level = 0, будет иметь только один index.level = 1

Кроме того: мне не важен порядок (самый большой), когда число одинаково.

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Хотя ответ @jezrael гораздо быстрее и проще (я буду его использовать), я разработал его, когда работал над ним:

df = pd.DataFrame({'A': ['A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2'],
      'B': ['B1', 'B1', 'B2', 'B2', 'B3', 'B3', 'B4', 'B5', 'B6', 'B7', 'B7', 'B8', 'B8']})

df = df.groupby(['A', 'B'])['A'].count()
df = df.groupby(level=0).nlargest(2).reset_index(level=0, drop=True)
df = df.unstack()

df_new = pd.DataFrame(columns=['A', '1_Largest', '2_largest'])

for i, row in enumerate(['A1', 'A2']):
    df_new.loc[i, :] = row
    df_new.loc[i, '1_Largest'] = df.loc[row].sort_values(ascending=False).index[0]
    df_new.loc[i, '2_largest'] = df.loc[row].sort_values(ascending=False).index[1]

df_new.set_index('A')
0 голосов
/ 16 мая 2018

Использовать SeriesGroupBy.value_counts, которые по умолчанию сортируются с выбором 2 верхних значений индекса по head, а затем DataFrame contructor:

a = df.groupby('A')['B'].apply(lambda x: x.value_counts().head(2).index.tolist())
print (a)
A
A1    [B1, B3]
A2    [B7, B8]
Name: B, dtype: object

Если хотите использовать свой код:

df = df.groupby(['A', 'B'])['A'].count()
df = df.groupby(level=0).nlargest(2).reset_index(level=0, drop=True)

df = df.rename('C').reset_index().groupby('A')['B'].apply(list)
print (df)
A
A1    [B1, B2]
A2    [B7, B8]
Name: B, dtype: object

df1 = (pd.DataFrame(a.values.tolist(), index=a.index)
         .rename(columns=lambda x: x+1)
         .add_suffix('_nlargest'))
print (df1)
   1_nlargest 2_nlargest
A                       
A1         B1         B3
A2         B7         B8
...