Сумма и количество значений по группам - PullRequest
1 голос
/ 27 сентября 2019

У меня есть этот набор данных с группой и продажами за период 1 и 2:

index = [1, 2, 3, 4, 5, 6]
a = ['A', 'B', 'A', 'B', 'C', 'B']
b = ['C', 'A', 'B', 'B', 'C', 'B']
c = [300, 109, 441, 375, 243, 340]
d = [359, 244, 155, 241, 429, 166]
df = pd.DataFrame({'ID': index, 'Group_1': a, 'Group_2': b, 'sales_1': c,'sales_2':d})

Я хочу посчитать количество клиентов в каждой группе со средним объемом продаж за этот период.Результат должен выглядеть следующим образом (я делаю это в Excel):

  Group  count_1  avg_sales_1  count_2  avg_sales_2
0     A        2      385.500        1      244.000
1     B        3      274.666        3      187.333
2     C        1      243.000        2      394.000

Я пробовал этот код, однако я мог делать только с одним периодом каждый раз:

df.groupby(['Group_1']).agg({'ID':'count', 'sales_1':'mean'})
df.groupby(['Group_2']).agg({'ID':'count', 'sales_2':'mean'})

Таккак мне объединить эти две группы в результате?Есть ли более быстрый способ выполнить эту задачу?

Ответы [ 2 ]

2 голосов
/ 27 сентября 2019

Я думаю, если только несколько групп, ваш солутон хорош.Только последнее использование concat с DataFrame.rename_axis и DataFrame.reset_index:

df1 = df.groupby(['Group_1']).agg({'ID':'count', 'sales_1':'mean'})
df2 = df.groupby(['Group_2']).agg({'ID':'count', 'sales_2':'mean'})
df = pd.concat([df1, df2], axis=1).rename_axis('Group').reset_index()
print (df)
  Group  ID     sales_1  ID     sales_2
0     A   2  370.500000   1  244.000000
1     B   3  274.666667   3  187.333333
2     C   1  243.000000   2  394.000000

Если возможно использование панд 0.25+, используйте именованная агрегация :

df1 = df.groupby(['Group_1']).agg(count_1=pd.NamedAgg(column='ID', aggfunc='count'),
                                  avg_sales_1=pd.NamedAgg(column='sales_1', aggfunc='mean'))

df2 = df.groupby(['Group_2']).agg(count_2=pd.NamedAgg(column='ID', aggfunc='count'),
                                  avg_sales_2=pd.NamedAgg(column='sales_2', aggfunc='mean'))

df = pd.concat([df1, df2], axis=1).rename_axis('Group').reset_index()
print (df)
  Group  count_1  avg_sales_1  count_2  avg_sales_2
0     A        2   370.500000        1   244.000000
1     B        3   274.666667        3   187.333333
2     C        1   243.000000        2   394.000000

Если много групп, то решение более сложное - сначала измените на wide_to_long, затем агрегируйте на GroupBy.agg и последнее изменение на DataFrame.unstack:

df = (pd.wide_to_long(df, 
                     stubnames=['Group','sales'],
                     i=['ID'],
                     j='g',
                     sep='_')).reset_index()

df = (df.groupby(['Group','g'])['sales'].agg([('count', 'count'), ('avg','mean')])
       .unstack()
       .sort_index(level=1, axis=1))
df.columns = [f'{a}_{b}' for a, b in df.columns]
df = df.reset_index()
print (df)
  Group       avg_1  count_1       avg_2  count_2
0     A  370.500000        2  244.000000        1
1     B  274.666667        3  187.333333        3
2     C  243.000000        1  394.000000        2
1 голос
/ 27 сентября 2019

Попробуйте это:

In [33]: df1 = df.groupby(['Group_1']).agg({'ID':'count', 'sales_1':'mean'})

In [34]: df2 = df.groupby(['Group_2']).agg({'ID':'count', 'sales_2':'mean'})

In [35]: pd.concat([df1,df2], axis=1)
Out[35]:
   ID     sales_1  ID     sales_2
A   2  370.500000   1  244.000000
B   3  274.666667   3  187.333333
C   1  243.000000   2  394.000000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...