Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有一种方法可以对分组进行加权平均滚动求和?_Python_Pandas - Fatal编程技术网

Python 有没有一种方法可以对分组进行加权平均滚动求和?

Python 有没有一种方法可以对分组进行加权平均滚动求和?,python,pandas,Python,Pandas,我想对数据帧应用加权和。过去我用过 for sec_id, sec_df_unidx in grouped: if sec_df_unidx.shape[0] > 3: pd.rolling_sum(sec_df[added_cols], 4) 我想对最新的值乘以0.6,第二个乘以0.2,第三个和第四个乘以0.1的总和应用加权平均值 DF: 带有新列的DF: DATE ID VALUE Weight_Sum 2012-12-31 A 100 Na

我想对数据帧应用加权和。过去我用过

for sec_id, sec_df_unidx in grouped:
    if sec_df_unidx.shape[0] > 3:
        pd.rolling_sum(sec_df[added_cols], 4)
我想对最新的值乘以0.6,第二个乘以0.2,第三个和第四个乘以0.1的总和应用加权平均值

DF:

带有新列的DF:

DATE    ID  VALUE   Weight_Sum
2012-12-31  A   100 NaN
2013-03-31  A   120 NaN
2013-06-30  A   140 NaN
2013-09-30  A   160 146
2013-12-31  A   180 166
2013-03-31  B   0   NaN
2013-06-30  B   5   NaN
2013-09-30  B   1   NaN
2013-12-31  B   3   2.5
2012-12-31  C   45  NaN
2013-03-31  C   46  NaN
2013-06-30  C   42  NaN
2013-09-30  C   30  35.5
2013-12-31  C   11  21.4
2012-12-31  D   18  NaN
2013-03-31  D   9   NaN
2013-06-30  D   13  NaN
2013-09-30  D   5   8.3
2013-12-31  D   11  9.8
2012-12-31  E   0   NaN
我可以用滚动申请或滚动总和来完成吗?还是我必须做一个for循环


谢谢。

我想你可以通过一个普通的
groupby/apply
调用的函数来实现。因此,类似于以下内容:

def roll_wsum(g,w,p):
    rsum = pd.rolling_apply(g.values,p,lambda x: np.dot(w,x),min_periods=p)
    return pd.Series(rsum,index=g.index)

weights = np.array([0.1,0.1,0.2,0.6])
df['wsum'] = df.groupby('ID')['VALUE'].apply(roll_wsum,weights,4)
print df
输出:

         DATE ID  VALUE   wsum
0  2012-12-31  A    100    NaN
1  2013-03-31  A    120    NaN
2  2013-06-30  A    140    NaN
3  2013-09-30  A    160  146.0
4  2013-12-31  A    180  166.0
5  2013-03-31  B      0    NaN
6  2013-06-30  B      5    NaN
7  2013-09-30  B      1    NaN
8  2013-12-31  B      3    2.5
9  2012-12-31  C     45    NaN
10 2013-03-31  C     46    NaN
11 2013-06-30  C     42    NaN
12 2013-09-30  C     30   35.5
13 2013-12-31  C     11   21.4
14 2012-12-31  D     18    NaN
15 2013-03-31  D      9    NaN
16 2013-06-30  D     13    NaN
17 2013-09-30  D      5    8.3
18 2013-12-31  D     11    9.8
19 2012-12-31  E      0    NaN
因此,我只是按“ID”对数据进行分组,然后将组的“VALUE”列发送到roll_wsum函数(以及加权和和和时段的权重)。
roll\u wsum
函数调用
rolling\u apply
并向
rolling\u apply
提供一个简单的lambda函数:“VALUE”和权重的点积。此外,这里施加
min_periods=4
条件也很关键,因为我们需要数组的长度(权重和df['VALUE'].values)相同

如果我使用点积来计算加权和,它可能无法按您希望的方式处理缺失值。因此,例如,您可能更喜欢以下内容(尽管这对示例数据没有影响):

         DATE ID  VALUE   wsum
0  2012-12-31  A    100    NaN
1  2013-03-31  A    120    NaN
2  2013-06-30  A    140    NaN
3  2013-09-30  A    160  146.0
4  2013-12-31  A    180  166.0
5  2013-03-31  B      0    NaN
6  2013-06-30  B      5    NaN
7  2013-09-30  B      1    NaN
8  2013-12-31  B      3    2.5
9  2012-12-31  C     45    NaN
10 2013-03-31  C     46    NaN
11 2013-06-30  C     42    NaN
12 2013-09-30  C     30   35.5
13 2013-12-31  C     11   21.4
14 2012-12-31  D     18    NaN
15 2013-03-31  D      9    NaN
16 2013-06-30  D     13    NaN
17 2013-09-30  D      5    8.3
18 2013-12-31  D     11    9.8
19 2012-12-31  E      0    NaN
def roll_wsum(g,w,p):
    rsum = pd.rolling_apply(g.values,p,lambda x: np.nansum(w*x),min_periods=p)
    return pd.Series(rsum,index=g.index)

weights = np.array([0.1,0.1,0.2,0.6])
df['wsum'] = df.groupby('ID')['VALUE'].apply(roll_wsum,weights,4)