【问题标题】:How do I calculate moving average with customized weight in pandas?如何在熊猫中使用自定义权重计算移动平均值?
【发布时间】:2019-01-31 03:47:17
【问题描述】:

我有一个包含两列 a: [1,2,3,4,5]; b: [1,0.4,0.3,0.5,0.2] 的数据框。我怎样才能使列 c :

c[0] = 1  
c[i] = c[i-1]*b[i]+a[i]*(1-b[i]) 

这样c:[1,1.6,2.58,3.29,4.658]

计算:

1 = 1
1*0.4+2*0.6 = 1.6
1.6*0.3+3*0.7 = 2.58
2.58*0.5+4*0.5 = 3.29
3.29*0.2+5*0.8 = 4.658

?

【问题讨论】:

  • 请正确格式化您的问题
  • 我没有看到预期的输出
  • 增加了预期输出
  • for 循环可能吗?
  • 我相信 for 循环是可行的,但我认为在 pandas 中必须有更好/更快的方法。

标签: python pandas performance numpy for-loop


【解决方案1】:

可能有更聪明的方法,但这是我的尝试:

import pandas as pd

a = [1,2,3,4,5]
b = [1,0.4,0.3,0.5,0.2]

df = pd.DataFrame({'a':a , 'b': b})

for i in range(len(df)):
    if i is 0:
        df.loc[i,'c'] = 1
    else:
        df.loc[i,'c'] = df.loc[i-1,'c'] * df.loc[i,'b'] + df.loc[i,'a'] * (1 - df.loc[i,'b'])

输出:

   a    b      c
0  1  1.0  1.000
1  2  0.4  1.600
2  3  0.3  2.580
3  4  0.5  3.290
4  5  0.2  4.658

【讨论】:

    【解决方案2】:

    我看不到向量化递归算法的方法。但是,您可以使用numba 来优化您当前的逻辑。这应该比常规循环更可取。

    from numba import jit
    
    df = pd.DataFrame({'a': [1,2,3,4,5],
                       'b': [1,0.4,0.3,0.5,0.2]})
    
    @jit(nopython=True)
    def foo(a, b):
        c = np.zeros(a.shape)
        c[0] = 1
        for i in range(1, c.shape[0]):
            c[i] = c[i-1] * b[i] + a[i] * (1-b[i])
        return c
    
    df['c'] = foo(df['a'].values, df['b'].values)
    
    print(df)
    
       a    b      c
    0  1  1.0  1.000
    1  2  0.4  1.600
    2  3  0.3  2.580
    3  4  0.5  3.290
    4  5  0.2  4.658
    

    【讨论】:

    • 感谢您的回答。逻辑似乎相同,那么为什么在这里使用 numba 更可取?
    • @serendipityo,因为numba 预编译了算法,而常规循环是纯Python。要查看影响,请在包含 @jit(nopython=True) 之前和之后运行代码。
    猜你喜欢
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    相关资源
    最近更新 更多