Python 熊猫:过去n天的平均值
我有一个Python 熊猫:过去n天的平均值,python,pandas,time-series,aggregation,Python,Pandas,Time Series,Aggregation,我有一个Pandas数据框,如下所示: test = pd.DataFrame({ 'Date' : ['2016-04-01','2016-04-01','2016-04-02', '2016-04-02','2016-04-03','2016-04-04', '2016-04-05','2016-04-06','2016-04-06'],
Pandas
数据框,如下所示:
test = pd.DataFrame({ 'Date' : ['2016-04-01','2016-04-01','2016-04-02',
'2016-04-02','2016-04-03','2016-04-04',
'2016-04-05','2016-04-06','2016-04-06'],
'User' : ['Mike','John','Mike','John','Mike','Mike',
'Mike','Mike','John'],
'Value' : [1,2,1,3,4.5,1,2,3,6]
})
Date User Value Value_Average_Past_2_days
0 2016-04-01 Mike 1.0 NaN
1 2016-04-01 John 2.0 NaN
2 2016-04-02 Mike 1.0 1.00
3 2016-04-02 John 3.0 2.00
4 2016-04-03 Mike 4.5 1.00
5 2016-04-04 Mike 1.0 2.75
6 2016-04-05 Mike 2.0 2.75
7 2016-04-06 Mike 3.0 1.50
8 2016-04-06 John 6.0 NaN
如下所示,数据集不一定每天都有观测值:
Date User Value
0 2016-04-01 Mike 1.0
1 2016-04-01 John 2.0
2 2016-04-02 Mike 1.0
3 2016-04-02 John 3.0
4 2016-04-03 Mike 4.5
5 2016-04-04 Mike 1.0
6 2016-04-05 Mike 2.0
7 2016-04-06 Mike 3.0
8 2016-04-06 John 6.0
我想添加一个新列,显示过去n天内每个用户的平均值(在本例中为n=2),如果至少有一天可用,否则它将具有nan
值。例如,在2016-04-06
上,John得到了一个nan
,因为他没有2016-04-05
和2016-04-04
的数据。所以结果会是这样的:
test = pd.DataFrame({ 'Date' : ['2016-04-01','2016-04-01','2016-04-02',
'2016-04-02','2016-04-03','2016-04-04',
'2016-04-05','2016-04-06','2016-04-06'],
'User' : ['Mike','John','Mike','John','Mike','Mike',
'Mike','Mike','John'],
'Value' : [1,2,1,3,4.5,1,2,3,6]
})
Date User Value Value_Average_Past_2_days
0 2016-04-01 Mike 1.0 NaN
1 2016-04-01 John 2.0 NaN
2 2016-04-02 Mike 1.0 1.00
3 2016-04-02 John 3.0 2.00
4 2016-04-03 Mike 4.5 1.00
5 2016-04-04 Mike 1.0 2.75
6 2016-04-05 Mike 2.0 2.75
7 2016-04-06 Mike 3.0 1.50
8 2016-04-06 John 6.0 NaN
在阅读了论坛上的几篇帖子后,我似乎应该将group\u by
和定制rolling\u mean
结合起来,但我不太明白怎么做
n = 2
# Cast your dates as timestamps.
test['Date'] = pd.to_datetime(test.Date)
# Create a daily index spanning the range of the original index.
idx = pd.date_range(test.Date.min(), test.Date.max(), freq='D')
# Pivot by Dates and Users.
df = test.pivot(index='Date', values='Value', columns='User').reindex(idx)
>>> df.head(3)
User John Mike
2016-04-01 2 1.0
2016-04-02 3 1.0
2016-04-03 NaN 4.5
# Apply a rolling mean on the above dataframe and reset the index.
df2 = (pd.rolling_mean(df.shift(), n, min_periods=1)
.reset_index()
.drop_duplicates())
# For Pandas 0.18.0+
df2 = (df.shift().rolling(window=n, min_periods=1).mean()
.reset_index()
.drop_duplicates())
# Melt the result back into the original form.
df3 = (pd.melt(df2, id_vars='Date', value_name='Value')
.sort_values(['Date', 'User'])
.reset_index(drop=True))
>>> df3.head()
Date User Value
0 2016-04-01 John NaN
1 2016-04-01 Mike NaN
2 2016-04-02 John 2.0
3 2016-04-02 Mike 1.0
4 2016-04-03 John 2.5
# Merge the results back into the original dataframe.
>>> test.merge(df3, on=['Date', 'User'], how='left',
suffixes=['', '_Average_past_{0}_days'.format(n)])
Date User Value Value_Average_past_2_days
0 2016-04-01 Mike 1.0 NaN
1 2016-04-01 John 2.0 NaN
2 2016-04-02 Mike 1.0 1.00
3 2016-04-02 John 3.0 2.00
4 2016-04-03 Mike 4.5 1.00
5 2016-04-04 Mike 1.0 2.75
6 2016-04-05 Mike 2.0 2.75
7 2016-04-06 Mike 3.0 1.50
8 2016-04-06 John 6.0 NaN
摘要
n = 2
test['Date'] = pd.to_datetime(test.Date)
idx = pd.date_range(test.Date.min(), test.Date.max(), freq='D')
df = test.pivot(index='Date', values='Value', columns='User').reindex(idx)
df2 = (pd.rolling_mean(df.shift(), n, min_periods=1)
.reset_index()
.drop_duplicates())
df3 = (pd.melt(df2, id_vars='Date', value_name='Value')
.sort_values(['Date', 'User'])
.reset_index(drop=True))
test.merge(df3, on=['Date', 'User'], how='left',
suffixes=['', '_Average_past_{0}_days'.format(n)])
我认为您可以使用第一个convert列
Date
,然后通过with和last查找缺少的Days
你用的是哪种版本的熊猫<代码>pd.\uuuu版本\uuuu谢谢。这是完美的语言。这段代码中是否有一个小的修改,以便我可以在过去n天内提取观察次数?可能使用
rolling(min\u periods=1,window=n)。sum(~is.null())
而不是rolling(min\u periods=1,window=2)。mean()
?我想你需要rolling(min\u periods=1,window=2)。count()
这肯定是一个很好的答案,但有没有办法分几个步骤来完成,因为我有一个类似的问题,而且我有一年的数据,所以每个步骤都非常耗时?