【问题标题】:pandas groupby apply function that take N-column frame and returns objectpandas groupby 应用函数,采用 N 列框架并返回对象
【发布时间】:2014-03-08 00:15:06
【问题描述】:

是否有类似的“转换”方法将函数应用于组(一次所有列)并返回一个对象?我尝试的任何操作似乎都会在组中的每列返回一个对象。

例如考虑数据

               Maturity                Date      s  Term  Month
0   2012-02-01 00:00:00 2012-01-03 00:00:00  2.993    29      2
18  2012-03-01 00:00:00 2012-01-03 00:00:00  3.022    58      3
57  2012-04-01 00:00:00 2012-01-03 00:00:00  3.084    89      4
117 2012-05-01 00:00:00 2012-01-03 00:00:00  3.138   119      5
...

假设我在 Date 上做一个 groupby 并将一些函数应用于由 (Term, Month, s) 标记的组。结果应该是这样的

               Maturity                result
2012-02-01 00:00:00 2012-01-03         object
2012-03-01 00:00:00 2012-01-03         object
2012-04-01 00:00:00 2012-01-03         object
....

我显然可以遍历组并汇总结果,但我想我只是错过了一些关于如何使用其中一种转换方法的明显内容。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您可以应用该函数,然后手动聚合每个组。例如,假设聚合是平均值,函数是列的总和,您可以:

    df.groupby("Date")['Term', 'Month', 's'].apply(lambda rows: np.mean(rows['Term'] + rows['Month'] + rows['s']))
    

    因此,如果我们假设 fit 方法从具有“月”、“期限”和“s”列的数据框构建一些模型:

    import pandas as pd
    import numpy as np 
    
    def fit (dataframe):
        return {  "param1": np.mean(dataframe["Term"]) + np.max(dataframe["month"]), "param2": np.std(dataframe["s"])} 
    

    还有一个包含一堆日期的列的数据框:

    df = pd.DataFrame({"date":  ["20140101", "20140202", "20140203"] * 4, "Term" : np.random.randint(100, size=12),"month": np.random.randint(12, size=12),"s": np.random.rand(12)*3})
    print df
    

    (输出:)

        Term      date  month         s
    0     24  20140101      6  2.364798
    1     43  20140202      9  0.066188
    2     59  20140203      6  1.078052
    3     40  20140101      3  1.982825
    4     34  20140202      4  2.089518
    5     20  20140203      1  2.412956
    6     84  20140101      8  0.779843
    7     62  20140202      9  0.918860
    8     32  20140203     11  2.613289
    9     16  20140101      9  0.788347
    10    23  20140202      6  0.982986
    11    27  20140203      1  0.658260
    

    然后我们可以一次对每组行的所有列应用 fit():

    modelPerDate = df.groupby("date").apply(fit)
    print modelPerDate
    

    它产生一个模型数据框,每个日期一个:

    date
    20140101    {'param2': 0.70786647858131047, 'param1': 50.0}
    20140202    {'param2': 0.71852297283637756, 'param1': 49.5}
    20140203    {'param2': 0.83876295773013798, 'param1': 45.5}
    

    【讨论】:

    • 这是一个类似'fit'的函数。不像'+'那样容易分解。
    • apply() 中收到的参数是一个数据框,包含一组行和 ['Term', 'Month', 's'] 选择的列,是否可以运行您的适合的方法呢?然后,您应该在每个日期获得一个合适的“对象”。我的示例中的“+”是添加列,然后平均值是将结果列表聚合为单个结果。
    • 我应该提到我可以使用 'apply' 或 'agg' 函数,但它为每一列返回相同的(冗余)对象。因此,看来我的函数每次都可以访问整个组(这是我想要的),但是对于组中的每一列都会调用一次(或者至少这是填充结果的方式)。
    • 嗯,我认为您对agg 的使用是正确的,但是apply 方法通常应该为每个组一次接收所有列。我在上面编辑了我的答案来说明这一点。
    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 2017-07-29
    • 2020-05-14
    • 2019-09-06
    • 1970-01-01
    • 2021-07-19
    • 2019-02-16
    • 2021-09-05
    相关资源
    最近更新 更多