Pandas: иерархическая группа с бункерами - PullRequest
1 голос
/ 22 апреля 2020

Я бы хотел агрегировать данные в pandas кадре данных, иерархически объединяя измерения и представляя их с помощью некоторого агрегата / представителя. При попытке сделать это следующим образом возникает исключение, указывающее на проблему с перекрывающимися индексами.

import pandas as pd

df = pd.DataFrame({
   'A': [1,1,2,2,3,3,4,4],
   'B': [5,7,5,6,7,7,6,7],
   'C': [1,1,1,1,1,1,1,1]
})

A_grouped = pd.cut(df['A'], bins=2) 
# groups: (0.997, 2.5], (2.5, 4.0]

B_grouped = df.groupby([A_grouped])['B'].apply(pd.cut, bins=2)
# groups: (0.997, 2.5]: (4.998, 6.0], (6.0, 7.0]
#         (2.5, 4.0]: (5.999, 6.5], (6.5, 7.0]

df_agg = df.groupby([A_grouped, B_grouped], as_index=False).agg(**{ 
        'A': ('A', 'min'), 
        'B': ('B', 'mean'), 
        'C': ('C', 'median'),
    })
# raises exception: cannot handle overlapping indices; use IntervalIndex.get_indexer_non_unique

print(df_agg)

# expected output
# A, B, C
# 1, 5.333, 1
# 1, 7, 1
# 3, 6, 1
# 3, 7, 1

Есть идеи, как этого добиться?

1 Ответ

2 голосов
/ 22 апреля 2020

Кажется, pandas имеет проблему при создании MultiIndex, когда есть интервалы на нескольких уровнях. Поскольку ваш вывод не заботится о группах, укажите labels=False, когда вы pd.cut, тогда группировка работает, так как ключи группировки представляют собой простые целые числа.

A_grouped = pd.cut(df['A'], bins=2, labels=False) 
B_grouped = df.groupby([A_grouped])['B'].apply(pd.cut, bins=2, labels=False)

df_agg = (df.groupby([A_grouped, B_grouped], as_index=False)
             .agg(**{'A': ('A', 'min'), 
                     'B': ('B', 'mean'), 
                     'C': ('C', 'median')}))

#   A         B  C
#0  1  5.333333  1
#1  1  7.000000  1
#2  4  6.000000  1    # <- Your expected A was wrong. 
#3  3  7.000000  1
...