【问题标题】:Creating custom aggregations dynamically to use with Pandas groupby动态创建自定义聚合以与 Pandas groupby 一起使用
【发布时间】:2021-07-31 20:19:30
【问题描述】:

我正在尝试动态创建一个 lambda 函数字典以传递给 Pandas 中的 agg() 函数并计算“异常”的数量。

    def prepareAggDict(defDict):
       aggdict={}  

       # iterate over features with upper limit threshold 
       for feature_a, threshold_a in defDict.items():
           aggdict[feature_a] = lambda x: (x >= threshold_a).sum()

       return(aggdict)

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

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

但由于某种原因,聚合仅应用 column_b 的第二项,而不应用 column_a 上的第一项。 我试图在 prepareAggDict 函数中将它们分成不同的 lambda,它运行良好。不幸的是,我必须为不同的列创建大约 7 个不同的阈值,我想通过将多个列名称及其阈值传递到一个方法来创建它,该方法将生成自定义聚合函数的字典,以使用 agg( )

例如:

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 组中的 column_a 的值为 1,B 的值为 2。

【问题讨论】:

    标签: python pandas pandas-groupby python-3.7


    【解决方案1】:

    使用lambda函数匹配dict中的dict.get,如果没有匹配则返回缺失值:

    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 未通过组值,这是nested functions 的可能解决方案:

    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
    

    【讨论】:

    • 感谢 jezrael,它确实有效,但是关于如何继续使用 prepareAggDict 有什么想法吗?我在这里简化了场景,我更愿意保留它。
    • 感谢@jezrael,它工作得很好。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    • 2020-10-05
    • 2017-07-02
    相关资源
    最近更新 更多