У меня есть dataframe, чем два столбца a: [1,2,3,4,5]; b: [1,0.4,0.3,0.5,0.2]
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
?
Я не вижу возможности для векторизации вашего рекурсивного алгоритма. Однако вы можете использовать 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
предварительно компилирует алгоритм, а обычный цикл - чистый Python. Чтобы увидеть результат, запустите код до и после включения @jit(nopython=True)
.
Там может быть более умный способ, но здесь моя попытка:
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