在 Python Pandas 中为 groupby 聚合函数应用过滤器

问题描述 投票:0回答:4

如何在 Pandas 中为 groupby 聚合函数应用过滤器?

我有DataFrame

data = {'Fruit':['apple', 'apple', 'apple', 'kivi', 'kivi', 'kivi'],
              'Y_or_N': ['Y', 'N', 'Y', 'N', 'N', 'Y'], 
              'A_or_B': ['A', 'A', 'B', 'A', 'B', 'A'],
              'Number': [3, 5, 6, 7, 2, 4]}

df = pd.DataFrame.from_dict(data)

我想要每个水果组的总和数字值在 3 列中:(1)所有值,(2)其中'Y_or_N'=='Y',(3)其中'A_or_B'=='A'。

我试过:

new_df = df.groupby(['Fruit']).apply(lambda x: x[x['Y_or_N'] == 'Y' ].agg(sum_Y=('Number', 'sum')))

这有效,但仅适用于 1 列。有没有有效的方法,如何为不同的列和聚合函数应用不同的过滤器?没有制作 3 df 然后将它们合并在一起。

期望的输出:

水果 sum_all sum_Y sum_A
苹果 14 9 8
基维 13 4 11
python pandas aggregate
4个回答
1
投票

我会先修改列,然后汇总:

(df.assign(sum_Y=lambda d: d['Number'].where(d['Y_or_N'].eq('Y')),
           sum_A=lambda d: d['Number'].where(d['A_or_B'].eq('A')),
          )
   .rename(columns={'Number': 'sum_all'})
   .groupby('Fruit', as_index=False)[['sum_all', 'sum_Y', 'sum_A']].sum()
)

输出:

   Fruit  sum_all  sum_Y  sum_A
0  apple       14    9.0    8.0
1   kivi       13    4.0   11.0

0
投票

这里有一个方法:

res = pd.DataFrame({
    'sum_all':df.groupby('Fruit').Number.sum(),
    'sum_Y':df[df.Y_or_N.eq('Y')].groupby('Fruit').Number.sum(),
    'sum_A':df[df.A_or_B.eq('A')].groupby('Fruit').Number.sum()}).reset_index()

输出:

   Fruit  sum_all  sum_Y  sum_A
0  apple       14      9      8
1   kivi       13      4     11

0
投票
import pandas as pd

data = {'Fruit':['apple', 'apple', 'apple', 'kivi', 'kivi', 'kivi'],
              'Y_or_N': ['Y', 'N', 'Y', 'N', 'N', 'Y'], 
              'A_or_B': ['A', 'A', 'B', 'A', 'B', 'A'],
              'Number': [3, 5, 6, 7, 2, 4]}

df = pd.DataFrame.from_dict(data)


r1 = df.groupby(['Fruit'])['Number'].sum()
r2 = df.groupby(['Fruit']).apply(lambda d: d[d['Y_or_N'].eq('Y')]['Number'].sum())
r3 = df.groupby(['Fruit']).apply(lambda d: d[d['A_or_B'].eq('A')]['Number'].sum())

r = pd.concat([r1, r2, r3], axis=1).set_axis(['Sum_All', 'Sum_Y', 'Sum_A'], axis='columns')

print(r)
       Sum_All  Sum_Y  Sum_A
Fruit                       
apple       14      9      8
kivi        13      4     11

0
投票

pd.pivot
的另一个选项:

res_df = df.pivot(index='Fruit', columns=['Y_or_N', 'A_or_B'], values='Number')
res_df = pd.concat([res_df.sum(1).to_frame('sum_all'),
                    res_df.xs('Y', axis=1).sum(1).to_frame('sum_Y'),
                    res_df.xs('A', level=1, axis=1).sum(1).to_frame('sum_A')], axis=1).reset_index()

   Fruit  sum_all  sum_Y  sum_A
0  apple     14.0    9.0    8.0
1   kivi     13.0    4.0   11.0
© www.soinside.com 2019 - 2024. All rights reserved.