serendipityo
serendipityo

Reputation: 21

How do I calculate moving average with customized weight in pandas?

I have a dataframe than contains two columns, a: [1,2,3,4,5]; b: [1,0.4,0.3,0.5,0.2]. How can I make a column c such that:

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

so that c:[1,1.6,2.58,3.29,4.658]

Calculation:

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

?

Upvotes: 1

Views: 174

Answers (2)

jpp
jpp

Reputation: 164643

I can't see a way to vectorise your recursive algorithm. However, you can use numba to optimize your current logic. This should be preferable to a regular loop.

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

Upvotes: 1

static const
static const

Reputation: 943

There could be a smarter way, but here's my attempt:

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'])

Output:

   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

Upvotes: 0

Related Questions