【问题标题】:Adaptive rolling mean in Pd.DataFramePd.DataFrame 中的自适应滚动平均值
【发布时间】:2020-10-29 01:12:04
【问题描述】:

我希望对数据帧进行滚动均值,但滚动均值必须覆盖时间戳中列的长度。

例如,在 time[1](只有一行)中,计算所有列 rows(1) 的滚动平均值,然后在 time[2] 中,对所有行 (2) 执行相同的操作,依此类推。随着时间戳的推进,窗口也随之推进。

此外,这是按组完成的。因此,如果它在 A 组上执行此操作,它必须进行某种重置,因为它会转到 B 组

有点像这个话题:Computing rolling mean in data.table with adaptive window lengths

但在 python 上,并考虑时间戳。

另外,数据集很大,所以它必须是最优的,迭代和循环需要数年时间

【问题讨论】:

  • 您能否提供数据集的最小部分以充分代表您的需求?
  • dataframe=pd.Dataframe({'timestamp':[0,1,2,3,4,0,1,2,3,4,5], 'user':['A','A','A','A','B','B','B','B','B'], 'answered_correctly':[0,1,1,0,1,1,1,0,0]})
  • 这将是数据集的一个示例。所以我需要获得用户的平均准确度,而不是从未来的时间戳中获取值,并考虑所有过去的时间戳。因此,对于用户 A,它将是 [0, 0.5 , 0.66 , 0.5]
  • 你试过下面的答案吗?

标签: python pandas dataframe


【解决方案1】:

简单移动平均线有一个固定大小的滑动窗口。滚动平均值是通过对 x(通常为常数)时间段内的时间序列数据进行平均来计算的。但是,您需要计算每个组的 answered_correctly 的累积移动平均值。如您在问题中所述,在计算平均值时,累积移动平均值会考虑所有先前的值。

import pandas as pd
df = pd.DataFrame({
    'timestamp'         :[3,1,2,3,4,0,1,2,0], 
    'user'              :['B','A','A','A','B','B','B','B','A'], 
    'answered_correctly':[0,1,1,0,1,1,1,0,0]
    })
    
# sort the dataframe by the timestamp
df.sort_values('timestamp', inplace=True)
df.groupby('user')['answered_correctly'].expanding().mean()

输出:

user   
A     8    0.000000
      1    0.500000
      2    0.666667
      3    0.500000
B     5    1.000000
      6    1.000000
      7    0.666667
      0    0.500000
      4    0.600000

如果您想访问群组A

df.groupby('user')['answered_correctly'].expanding().mean().A

输出:

8    0.000000
1    0.500000
2    0.666667
3    0.500000
Name: answered_correctly, dtype: float64

如果您想访问A 组的值:

df.groupby('user')['answered_correctly'].expanding().mean().A.get_values()

输出:

array([0.        , 0.5       , 0.66666667, 0.5       ])

【讨论】:

  • 真正的男人。我实际上找到了一个不同的解决方案。我会测试两者并进行比较。由于我正在处理一个非常大的数据集,因此每次优化都很重要。
【解决方案2】:

如果有人遇到同样的问题,Ozturkib 回答的另一种方法是:

by = ['user_id']
on = ['answered_correctly']
how = ['count']



agg = train.groupby(by)[on].apply(lambda x: (
    x
    .shift(1)
    .rolling(window=len(x), min_periods=1)
    .agg(how)))

这会将 NAN 留在第一行,在我的情况下,我更喜欢这些 NAN,但如果您不想要它们,只需将“min_periods”设置为 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-20
    • 2020-07-15
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2021-05-08
    相关资源
    最近更新 更多