更新了附加信息
data:
import pandas as pd
import numpy as np
df = pd.DataFrame({'date':['2018-01-01', '2018-02-01', '2018-03-01', '2018-04-01']*4,
'country_id':[1]*8+[2]*8,
'company_id':[1]*4+[2]*4+[1]*4+[2]*4,
'value':[1, 0, 2, np.nan, 1, 2, np.nan, np.nan, 3, 0, 2, np.nan, 1, 2, np.nan, np.nan]})
在短短时间内创建滚动总和country_id
df['rolling_sum'] = df.groupby('country_id').apply(lambda x: x.value.rolling(window=2, min_periods=1).sum()).reset_index(drop=True)
在短短时间内创建滚动计数country_id
df['sum_records'] = df.groupby('country_id').apply(lambda x: x.value.rolling(window=2, min_periods=1).count()).reset_index(drop=True)
现在 groupby 内country_id
and date
,对总和进行求和,然后除以计数总和
summarized_df = df.groupby(['country_id', 'date']).apply(lambda x: x.rolling_sum.sum()/x.sum_records.sum()).reset_index()
country_id date
1 2018-01-01 1.000000
2018-02-01 1.000000
2018-03-01 1.333333
2018-04-01 2.000000
2 2018-01-01 2.000000
2018-02-01 1.500000
2018-03-01 1.333333
2018-04-01 2.000000
让我们更详细地看看这个。由于我们按国家/地区 ID 进行分组,因此我们将提取单个国家/地区 ID 来实践此方法:
如果我们只取其中的一块,比如说country_id == 1
:
df2 = df[df['country_id'] == 1]
date country_id company_id value
0 2018-01-01 1 1 1.0
1 2018-02-01 1 1 0.0
2 2018-03-01 1 1 2.0
3 2018-04-01 1 1 NaN
4 2018-01-01 1 2 1.0
5 2018-02-01 1 2 2.0
6 2018-03-01 1 2 NaN
7 2018-04-01 1 2 NaN
如果我们想要这个的滚动平均值,我们可以这样做:
df2.value.rolling(window=2, min_periods=1).mean()
0 1.0
1 0.5
2 1.0
3 2.0
4 1.0
5 1.5
6 2.0
7 NaN
我们可以在这里看到子集country_id == 1 数据帧中的值以及它们与滚动平均值的关系:
0 1.0 = (1)/1 = 1
1 0.0 = (0 + 1)/2 = 0.5
2 2.0 = (2 + 0)/2 = 1
3 NaN = (Nan + 2)/1 = 2
4 1.0 = (1 + Nan)/1 = 1
5 2.0 = (2 + 1)/2 = 1.5
6 NaN = (Nan + 2)/1 = 2
7 NaN = (Nan + Nan)/0 = Nan
这就是我们获得单个分组的滚动平均值的方法country_id
If我们想要按日期进行分组,我们首先按country_id进行分组,然后按日期进行分组,单个组如下所示:
df3 = df[(df['country_id'] == 1) & (df['date'] == '2018-03-01')]
df3.value
2 2.0
6 NaN
df3.value.rolling(window=2, min_periods=1).mean()
2 2.0
6 2.0
df3.value
2 2.0 = (2)/1 = 2
6 NaN = (Nan + 2)/1 = 2
这里的问题是你想要滚动平均值first by country_id
,不与分组date
. Then找到按国家/地区划分的滚动平均值后,您想要采取those值并求平均值。如果我们要采取滚动averages, 进而average那些,结果会是错误的。
那么让我们回到我们创建的原始滚动平均值country_id == 1
,然后查看日期:
2018-01-01 1.0 = (1)/1 = 1
2018-02-01 0.0 = (0 + 1)/2 = 0.5
2018-03-01 2.0 = (2 + 0)/2 = 1
2018-04-01 NaN = (Nan + 2)/1 = 2
2018-01-01 1.0 = (1 + Nan)/1 = 1
2018-02-01 2.0 = (2 + 1)/2 = 1.5
2018-03-01 NaN = (Nan + 2)/1 = 2
2018-04-01 NaN = (Nan + Nan)/0 = Nan
现在这里棘手的部分是,此时我们不能只是将它们平均在一起,因为例如,如果您查看 2018-03-01 滚动平均值,我们有 1 和 2,即 3。将其除以 2 将得到我们1.5。
我们必须首先sum滚动值,然后除以记录数。