【问题标题】:Group by date and sum columns按日期和总和列分组
【发布时间】:2026-01-30 15:10:02
【问题描述】:

我有一个设计选择不佳的数据框,如下所示:

df = pd.DataFrame({
    'Day': ['2021-03-01', '2021-03-01', '2021-03-02', '2021-03-02', '2021-03-03'],
    'Name': ['Sam', 'Sam', 'Jack', 'Steve', 'Steve'],
    'Fruit':['Apple', 'Apple', 'Banana', 'Apple', 'Banana'],
    '2021-03-01':['2', '1', '0', '1', '1'],
    '2021-03-02': ['3', '5', '4', '2', '1'],
    '2021-03-03':['7', '3', '2', '1', '4']})

df
          Day   Name   Fruit 2021-03-01 2021-03-02 2021-03-03
0  2021-03-01    Sam   Apple          2          3          7
1  2021-03-01    Sam   Apple          1          5          3
2  2021-03-02   Jack  Banana          0          4          2
3  2021-03-02  Steve   Apple          1          2          1
4  2021-03-03  Steve  Banana          1          1          4

我希望,对于Day 中的每个日期,对应于与Day 的值具有相同列名的列中的日期,将其他变量分组并按总和聚合它们。 例如,如果Day 的值为“2021-03-01”,那么在“2021-03-01”列中,我将对值求和(此列中苹果的 nr 和香蕉的 nbr)。

它希望结果数据框看起来像这样:

         Date   Name  nrApples  nrBananas
0  2021-03-01    Sam         3          0
1  2021-03-02   Jack         0          4
2  2021-03-02  Steve         2          0
3  2021-03-03  Steve         0          4

问题是我有很多这些日期列,我不知道如何检查Day列中的值是否与列名相同,并聚合它的值. 感谢您的帮助。

【问题讨论】:

    标签: python pandas numpy


    【解决方案1】:

    融合列,将 Day 列与包含 Days、groupby、aggregate(sum)、unstack 和 reset 索引的 variable 列进行比较:

    (df
     .melt(['Day', 'Name', 'Fruit'])
     .loc[lambda df: df.Day.eq(df.variable)]
     .astype({"value": int})
     .groupby(['Day', 'Name', 'Fruit'])['value']
     .sum()
     .unstack(fill_value = 0)
     .add_prefix("nr")
     .reset_index()
     .rename_axis(columns = None)
     )
     
    Fruit         Day   Name  nrApple  nrBanana
    0      2021-03-01    Sam        3         0
    1      2021-03-02   Jack        0         4
    2      2021-03-02  Steve        2         0
    3      2021-03-03  Steve        0         4
    

    【讨论】:

    • 效果很好,谢谢!!如果我想对所有日期列求和,你知道我是否可以修改它? (不管Day是否相同)
    • 你应该可以修改和。如果您有任何问题,请询问。
    【解决方案2】:
    def fn(x):
        return (
            x.set_index("Fruit")
            .loc[:, x.Day.iat[0]]
            .astype(int)
            .groupby(level=0)
            .sum()
            .to_dict()
        )
    
    
    df = (
        df.groupby(["Day", "Name"])
        .apply(fn)
        .apply(pd.Series)
        .add_prefix("nr")
        .reset_index()
        .fillna(0)
    )
    print(df)
    

    打印:

              Day   Name  nrApple  nrBanana
    0  2021-03-01    Sam      3.0       0.0
    1  2021-03-02   Jack      0.0       4.0
    2  2021-03-02  Steve      2.0       0.0
    3  2021-03-03  Steve      0.0       4.0
    

    【讨论】: