Python 动态创建自定义聚合以与groupby一起使用

Python 动态创建自定义聚合以与groupby一起使用,python,pandas,pandas-groupby,python-3.7,Python,Pandas,Pandas Groupby,Python 3.7,我试图动态创建一个lambda函数字典,将其传递到Pandas中的agg()函数中,并计算“异常”的数量 我希望通过以下方式传递具有不同阈值的不同字段名: aggdict = prepareAggDict({"column_a":3500, "column_b":8200}) dailyAgg = df.groupby([id_col,Date_col]).agg(aggdict) 但出于某种原因,聚合只应用列_b的第二项,而不应用列_a的第一项。

我试图动态创建一个lambda函数字典,将其传递到Pandas中的agg()函数中,并计算“异常”的数量

我希望通过以下方式传递具有不同阈值的不同字段名:

aggdict = prepareAggDict({"column_a":3500, "column_b":8200})   
dailyAgg = df.groupby([id_col,Date_col]).agg(aggdict)
但出于某种原因,聚合只应用列_b的第二项,而不应用列_a的第一项。 我试着在prepareAggDict函数中将它们分成不同的lambda,它工作得很好。不幸的是,我必须为不同的列创建大约7个不同的阈值,我想通过将多个列名称及其阈值传递到一个方法来创建它,该方法将生成自定义聚合函数的字典,并通过agg()传递给groupby

例如:

data = {
    "id_col":["A","A","B","B","B"],
    "column_a":[500,4500,8100,300,11500],
    "column_b":[800,22340,7554,300,900]
}
df = pd.DataFrame(data)

aggdict = prepareAggDict({"column_a":3500, "column_b":8200})   
dailyAgg = df.groupby(["id_col"]).agg(aggdict)
将产生:


我希望a组中的列a的值为1,B的值为2。

使用lambda函数在
dict.get
中通过
dict
进行匹配,如果没有返回匹配项,则返回缺少的值:

aggdict = {"column_a":3500, "column_b":8200}
dailyAgg = df.groupby(["id_col"]).agg(lambda x: (x >= aggdict.get(x.name, np.nan)).sum())
print (dailyAgg)
        column_a  column_b
id_col                    
A              1         1
B              2         0
编辑:我认为在您的解决方案中,对于组值,未传递
x
,以下是可能的解决方案:


谢谢jezrael,它确实有效,但是关于如何保持使用prepareAggDict有什么想法吗?我在这里简化了场景,我更愿意保留它。@NivCohen-answer已编辑。谢谢@jezrael,效果很好。非常感谢。
aggdict = {"column_a":3500, "column_b":8200}
dailyAgg = df.groupby(["id_col"]).agg(lambda x: (x >= aggdict.get(x.name, np.nan)).sum())
print (dailyAgg)
        column_a  column_b
id_col                    
A              1         1
B              2         0
def prepareAggDict(p):
    def ipf(x):
        return (x >= p).sum()
    return ipf 

    
data = {
    "id_col":["A","A","B","B","B"],
    "column_a":[500,4500,8100,300,11500],
    "column_b":[800,22340,7554,300,900]
}
df = pd.DataFrame(data)

d = {"column_a":3500, "column_b":8200}
aggdict = {k: prepareAggDict(v) for k, v in d.items()}

#return same like
#aggdict = {"column_a":prepareAggDict(3500), "column_b":prepareAggDict(8200)} 

dailyAgg = df.groupby(["id_col"]).agg(aggdict)
print (dailyAgg)
        column_a  column_b
id_col                    
A              1         1
B              2         0