【问题标题】:Using groupby's aggregation to populate a new column使用 groupby 的聚合填充新列
【发布时间】:2021-11-22 11:54:44
【问题描述】:

鉴于此数据框 df:

date          type     target
2021-01-01    0        5
2021-01-01    0        6
2021-01-01    1        4
2021-01-01    1        2
2021-01-02    0        5
2021-01-02    1        3
2021-01-02    1        7
2021-01-02    0        1
2021-01-03    0        2
2021-01-03    1        5

我想创建一个新列,其中包含按类型划分的昨天的目标平均值。

例如,对于第 5 行 (date=2021-01-02, type=0),新列的值将是 5.5,作为前一天目标的平均值,2021-01-01 for type= 0 是 (5+6)/2。

我可以很容易地按日期和类型获得目标分组的平均值:

means = df.groupby(['date', 'type'])['target'].mean()

但我不知道如何使用所需数据在原始数据框上创建一个新列,该列应如下所示:

date          type     target      mean
2021-01-01    0        5           NaN (or null or whatever)
2021-01-01    0        6           NaN
2021-01-01    1        4           NaN
2021-01-01    1        2           NaN
2021-01-02    0        5           5.5
2021-01-02    1        3           3
2021-01-02    1        7           3
2021-01-02    0        2           5.5
2021-01-03    0        2           3.5
2021-01-03    1        5           5

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    确保您的日期列是datetime,并将另一个临时列添加到前一天日期的df

     df['date'] = pd.to_datetime(df['date'])
     df['yesterday'] = df['date'] - pd.Timedelta('1 day')
    

    然后使用 groupbyas_index=False 的方式,然后将其合并到昨天/日期的原始 df 并键入列,然后选择所需的列:

    means = df.groupby(['date', 'type'], as_index=False)['target'].mean()
    df.merge(means, left_on=['yesterday', 'type'], right_on=['date', 'type'], 
    how='left', suffixes=[None, ' mean'])[['date', 'type', 'target', 'target mean']]
    

    输出:

            date  type  target  target mean
    0 2021-01-01     0       5          NaN
    1 2021-01-01     0       6          NaN
    2 2021-01-01     1       4          NaN
    3 2021-01-01     1       2          NaN
    4 2021-01-02     0       5          5.5
    5 2021-01-02     1       3          3.0
    6 2021-01-02     1       7          3.0
    7 2021-01-02     0       1          5.5
    8 2021-01-03     0       2          3.0
    9 2021-01-03     1       5          5.0
    

    【讨论】:

      【解决方案2】:

      想法是通过TimedeltaMultiIndex Series 的第一级添加一天,因此可以通过DataFrame.join 添加新列:

      df['date'] = pd.to_datetime(df['date'])
      
      s1 = df.groupby(['date', 'type'])['target'].mean()
      s2 = s1.rename(index=lambda x: x + pd.Timedelta(days=1), level=0)
      
      df = df.join(s2.rename('mean'), on=['date','type'])
      print (df)
              date  type  target  mean
      0 2021-01-01     0       5   NaN
      1 2021-01-01     0       6   NaN
      2 2021-01-01     1       4   NaN
      3 2021-01-01     1       2   NaN
      4 2021-01-02     0       5   5.5
      5 2021-01-02     1       3   3.0
      6 2021-01-02     1       7   3.0
      7 2021-01-02     0       1   5.5
      8 2021-01-03     0       2   3.0
      9 2021-01-03     1       5   5.0
      

      另一种解决方案:

      df['date'] = pd.to_datetime(df['date'])
      
      s1 = df.groupby([df['date'] + pd.Timedelta(days=1), 'type'])['target'].mean()
      df = df.join(s1.rename('mean'), on=['date','type'])
      print (df)
              date  type  target  mean
      0 2021-01-01     0       5   NaN
      1 2021-01-01     0       6   NaN
      2 2021-01-01     1       4   NaN
      3 2021-01-01     1       2   NaN
      4 2021-01-02     0       5   5.5
      5 2021-01-02     1       3   3.0
      6 2021-01-02     1       7   3.0
      7 2021-01-02     0       1   5.5
      8 2021-01-03     0       2   3.0
      9 2021-01-03     1       5   5.0
      

      【讨论】:

        【解决方案3】:

        @Emi OB 的回答小版

        means = df.groupby(["date", "type"], as_index=False)["target"].mean()
        means["mean"] = means.pop("target").shift(2)
        df = df.merge(means, how="left", on=["date", "type"])
        
        
            date    type    target  mean
        0   2021-01-01  0   5   NaN
        1   2021-01-01  0   6   NaN
        2   2021-01-01  1   4   NaN
        3   2021-01-01  1   2   NaN
        4   2021-01-02  0   5   5.5
        5   2021-01-02  1   3   3.0
        6   2021-01-02  1   7   3.0
        7   2021-01-02  0   2   5.5
        8   2021-01-03  0   2   3.5
        9   2021-01-03  1   5   5.0
        

        【讨论】:

          猜你喜欢
          • 2017-07-20
          • 2019-12-22
          • 2017-10-29
          • 2021-05-28
          • 2021-10-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多