Pandas 分组聚合:汇总和条件

4

我正在对一个PD数据框进行按项目日期对分组,并希望在更大的聚合函数中添加一些自定义条件函数,这些函数使用lambda实现。

使用这里的提示,我可以执行以下操作,它可以正确地计算给定列中的正数和负数。

item_day_count=item_day_group['PriceDiff_pct'].agg({'Pos':lambda val: (val > 0).sum(),'Neg':lambda val: (val <= 0).sum()}).reset_index()

我还可以使用另一种聚合方式,其中包含预先构建的聚合和自定义百分位数函数,以返回正确的统计数据:

item_day_count_v2=item_day_group['PriceDiff_pct'].agg(['count','min',percentile(25),'mean','median',percentile(75),'max']).reset_index()

但我不知道如何将它们合并为一个更大的函数 - 当我尝试以下操作时,我收到错误:AttributeError: 'DataFrameGroupBy' object has no attribute 'name'

item_day_count_v3=item_day_group['PriceDiff_pct'].agg(['count',{'Pos_Return':lambda val: (val > 0).sum(),'Neg_Return':lambda val: (val <= 0).sum()},'min',percentile(25),'mean','median',percentile(75),'max']).reset_index() 

有人知道如何将这些功能组合起来吗?看起来我很接近了,因为它们分别都能正常工作。感谢您的帮助!

3个回答

2

我不建议将一个已定义的函数与本地聚合器结合在字典中。您可以将它们作为元组列表传递,包括函数名和函数,如下所示:

item_day_count_v3 = item_day_group['PriceDiff_pct'].agg([
    ('Count', 'count'), 
    ('Pos_Return', lambda val: (val > 0).sum()), 
    ('Neg_Return', lambda val: (val < 0).sum()), 
    ('Mean', 'mean'), 
    ('Median', 'median'), 
    ('25%Percntile', percentile(25)), 
    ('75%Percntile', percentile(75)), 
    ('Max', 'max')
]).reset_index()

函数名将成为列名。


0

从pandas docs的aggregate()方法中:

可接受的组合方式包括:

  • 字符串函数名

  • 函数

  • 函数列表

  • 列名 -> 函数(或函数列表)的字典

虽然我认为它并不支持所有的组合方式。

所以,你可以尝试这样做:

首先将所有内容放入一个字典中,然后使用该字典进行聚合。

# The functions to agg on every column.
agg_dict = dict((c, ['count','min',percentile(25),'mean','median',percentile(75),'max']) for c in item_day.columns.values)

# Append to the dict the column-specific functions.
agg_dict['Pos_Return'] = lambda val: (val > 0).sum()
agg_dict['Neg_Return'] = lambda val: (val <= 0).sum()

# Agg using the dict.
item_day_group['PriceDiff_pct'].agg(agg_dict)

0

正如其他人所说,您不能在agg()方法中混合使用命名函数和字典。

这里有一种实用的方法来实现您想要的。让我们构造一些数据。

df = pd.DataFrame({'A':['x', 'y']*3,
                   'B':[10,20,30,40,50,60]})

df
Out[38]: 
   A   B
0  x  10
1  y  20
2  x  30
3  y  40
4  x  50
5  y  60

定义一个函数来计算大于或等于30的值的数量。
def ge30(x):
    return (x>=30).sum()

现在在 groupby().agg() 中使用您的自定义函数。

df.groupby('A').agg(['sum', 'mean', ge30])
Out[40]: 
     B          
   sum mean ge30
A               
x   90   30    2
y  120   40    2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接