【问题标题】:mean per group in a fragmented dataset碎片数据集中每组的平均值
【发布时间】:2022-10-30 16:13:04
【问题描述】:

这实际上是我之前问题的延伸,但我被要求将其作为一个单独的问题 Rolling average on previous dates per group

我有以下数据集:

Name    Loc     Site    Date    Total
Alex    Italy   A   12.31.2020  30
Alex    Italy   B   12.31.2020  20
Alex    Italy   B   12.30.2020  100
Alex    Italy   B   12.28.2020  40
Alex    Italy   A   12.23.2020  80
Alex    France  A   12.28.2020  10
Alex    France  B   12.28.2020  20
Alex    France  B   12.23.2020  10
Alex    France  A   12.23.2020  100
Alex    France  B   12.21.2020  25

我想在每个名称、位置和日期的日期之前的任意时间范围内为每一行添加总计的平均值

这是我在前 5 天寻找的结果(不包括日期):

Name    Loc    Site Date      Total Prv_Avg
Alex    Italy   A   12.31.2020  30  70
Alex    Italy   B   12.31.2020  20  70
Alex    Italy   B   12.30.2020  100 40
Alex    Italy   B   12.28.2020  40  80
Alex    Italy   A   12.23.2020  80  NaN
Alex    France  A   12.28.2020  10  55
Alex    France  B   12.28.2020  20  55
Alex    France  B   12.23.2020  10  25
Alex    France  A   12.23.2020  100 25
Alex    France  B   12.21.2020  25  NaN

Null 用于数据中没有前 5 天的行

【问题讨论】:

  • Prv_Avg 列的前两个值不应该是 100 而不是 70?
  • 不,对于 31.12,它将计算 30.12 和 28.12(均在 5 天内,不包括 31.12)

标签: python pandas group-by time-series


【解决方案1】:

GroupBy.transform 中使用自定义 lambda 函数,将匹配值替换为 NaN,并通过 numpy.nanmean 创建平均值:

df['Date'] = pd.to_datetime(df['Date'])


def f(x):
    arr = x.index.to_numpy()
    s = x.to_numpy()
    prev = arr - pd.Timedelta(5, 'day')
    return np.nanmean(np.where((arr[:, None] > arr) & 
                               (arr >= prev[:, None]), s, np.nan), axis=1)


df['Prv_Avg'] = (df.set_index('Date')
                   .groupby(['Name','Loc'])['Total']
                   .transform(f)
                   .to_numpy())
print (df)
   Name     Loc Site       Date  Total  Prv_Avg
0  Alex   Italy    A 2020-12-31     30     70.0
1  Alex   Italy    B 2020-12-31     20     70.0
2  Alex   Italy    B 2020-12-30    100     40.0
3  Alex   Italy    B 2020-12-28     40     80.0
4  Alex   Italy    A 2020-12-23     80      NaN
5  Alex  France    A 2020-12-28     10     55.0
6  Alex  France    B 2020-12-28     20     55.0
7  Alex  France    B 2020-12-23     10     25.0
8  Alex  France    A 2020-12-23    100     25.0
9  Alex  France    B 2020-12-21     25      NaN

【讨论】:

  • 嗨,@jezrael,早上好!我不确定 OP 的预期输出是否一致。对于法国,您的结果与预期输出不匹配。此外,我对 OP 的前一个问题的解决方案也适用于这个新问题,但与意大利的预期输出不匹配。
  • @PaulS - 是的,样本数据似乎 110 不匹配,我猜是错字。或者OP需要别的东西;)
  • 嗨,我检查了我的输出并且它是一致的,在我的示例中无论如何都不应该显示 110
  • @Alex - 如果检查print (s) 的输出有2020-12-30 100.0,那么它在2020-12-28 40.0 之后3 天。那么为什么预期的输出是 12.28.2020 10 55 ?计数55 怎么样?
  • @jezrael,对于 Alex + France 组,如果您查看 28.12.2020,我需要查看前 5 天的平均值,不包括 28.12。因此,平均值为 23-27.12。在这种情况下,唯一相关的日期是 23 日,有两个样本 - 100 和 10,因此平均值为 55。
猜你喜欢
  • 2021-12-22
  • 1970-01-01
  • 2022-08-18
  • 2017-11-12
  • 2019-07-05
  • 2017-03-05
  • 2021-11-08
相关资源
最近更新 更多