如何用滚动平均窗口总结多个熊猫数据框?
Posted
技术标签:
【中文标题】如何用滚动平均窗口总结多个熊猫数据框?【英文标题】:How to sum up multiple pandas dataframes with a rolling average window? 【发布时间】:2021-09-20 15:48:41 【问题描述】:我在我的数据框 df 上使用滚动窗口和移位。
import pandas as pd
from functools import reduce
df = pd.DataFrame(
'date': ['2021-01-01','2021-01-02', '2021-01-03', '2021-01-04', '2021-01-05','2021-01-06','2021-01-07','2021-01-08','2021-01-09','2021-01-10'],
'value': [10,20,20,30,20,10,30,20,10,20]
)
df.date = pd.to_datetime(df.loc[:, 'date'], format='%Y-%m-%d')
df.set_index('date',inplace=True)
df
value
date
2021-01-01 10
2021-01-02 20
2021-01-03 20
2021-01-04 30
2021-01-05 20
2021-01-06 10
2021-01-07 30
2021-01-08 20
2021-01-09 10
2021-01-10 20
我想得到一个数据框 df_all,它看起来像这样。 01-04 的值为 (10+20+20)/3 = 17,01-05 的值为 17+ (20+20+30)/3 = 40,01-06 的值为 17+( 20+20+30)/3+(20+30+20)/3=63 以此类推。
注意班次(时间间隔)重复5天,所以01-09是23+23+20+20+20 =106,01-10 =23+20+20+20+20 = 103 .
value
date
2021-01-01 0.0
2021-01-02 0.0
2021-01-03 0.0
2021-01-04 17.0
2021-01-05 40.0
2021-01-06 63.0
2021-01-07 83.0
2021-01-08 103.0
2021-01-09 106.0
2021-01-10 103.0
我通过这段代码实现了这一点:
df1 = (((df.rolling(3)).mean())).shift(1).rolling(1).mean().fillna(0).round()
df2 = (((df.rolling(3)).mean())).shift(2).rolling(1).mean().fillna(0).round()
df3 = (((df.rolling(3)).mean())).shift(3).rolling(1).mean().fillna(0).round()
df4 = (((df.rolling(3)).mean())).shift(4).rolling(1).mean().fillna(0).round()
df5 = (((df.rolling(3)).mean())).shift(5).rolling(1).mean().fillna(0).round()
df_all = reduce(lambda i, j: i.add(j, fill_value=0), [df1, df2, df3, df4, df5])
df_all
但是,我的真实数据集非常大,其中有 70 个班次(这是医学数据中的时间间隔)。 所以我要 df1, df2,.... df70 很费力。
有人可以帮助我为我的问题提供更紧凑的代码吗?我想这将是某种循环。谢谢。
P.S.
to aid the understanding of this problem, imagine these numbers horizontally as one line. then you shift this line 1 column to the right, and then again and again up to 5 times.
10,20,20,30,20,10,30,20,10,20
10,20,20,30,20,10,30,20,10,20
10,20,20,30,20,10,30,20,10,20
10,20,20,30,20,10,30,20,10,20
10,20,20,30,20,10,30,20,10,20
First 10 column totals:
10,30,50,80,100,100,110,110,80,90.
(in my example, these are taken as 3-day averages).
【问题讨论】:
解释一下你是怎么得到2021-01-09 106.0
的?
是的,刚刚添加!
10,30,50,80,100,100,110,110,80,90
应该是10,30,50,80,100,100,110,110,90,90
?
【参考方案1】:
IIUC,这是一种方法:
df['value'] = df.rolling(3).mean().shift().cumsum().fillna(0).round()
print(df)
输出:
value
date
2021-01-01 0.0
2021-01-02 0.0
2021-01-03 0.0
2021-01-04 17.0
2021-01-05 40.0
2021-01-06 63.0
2021-01-07 83.0
2021-01-08 103.0
2021-01-09 123.0
2021-01-10 143.0
【讨论】:
非常感谢。我不知道 cumsum() :) 它说接受你的答案还为时过早。 等等。我实际上需要在 shift(5) 处停下来......但我的日期比这长。所以我在df中添加了最后两行。 @bluetail 您需要在 shift(5) 处停止是什么意思?你能更新问题并详细解释一下吗? 是的,我已经更新了问题和输出。【参考方案2】:由于您编辑了您的帖子,@Nk03 的答案不完整。
使用np.cumsum
避免多次滚动:
df['value'] = df.rolling(3).mean().shift().cumsum().fillna(0).round()
df['value'] = df['value'].sub(df['value'].shift(5, fill_value=0))
>>> df
value
date
2021-01-01 0.0
2021-01-02 0.0
2021-01-03 0.0
2021-01-04 17.0
2021-01-05 40.0
2021-01-06 63.0
2021-01-07 83.0
2021-01-08 103.0
2021-01-09 106.0
2021-01-10 103.0
【讨论】:
以上是关于如何用滚动平均窗口总结多个熊猫数据框?的主要内容,如果未能解决你的问题,请参考以下文章