Как рассчитать скользящее среднее с индивидуальным весом в пандах?

1

У меня есть 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

?

  • 0
    Пожалуйста, отформатируйте ваш вопрос соответствующим образом
  • 0
    Я не вижу ожидаемого выхода
Показать ещё 3 комментария
Теги:
pandas
numpy
performance
for-loop

2 ответа

1

Я не вижу возможности для векторизации вашего рекурсивного алгоритма. Однако вы можете использовать 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
  • 0
    Спасибо за Ваш ответ. Логика кажется той же самой, и поэтому, почему использование numba здесь более предпочтительно?
  • 0
    @serendipityo, потому что numba предварительно компилирует алгоритм, а обычный цикл - чистый Python. Чтобы увидеть результат, запустите код до и после включения @jit(nopython=True) .
0

Там может быть более умный способ, но здесь моя попытка:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню