Панды последовательно применяют функцию, используя вывод предыдущего значения

Я хочу вычислить "перенос" серии. Это вычисляет значение для каждой строки, а затем добавляет его к ранее вычисленному значению (для предыдущей строки).

Как мне сделать это в пандах?

decay = 0.5
test = pd.DataFrame(np.random.randint(1,10,12),columns = ['val'])
test
    val
0   4
1   5
2   7
3   9
4   1
5   1
6   8
7   7
8   3
9   9
10  7
11  2

decayed = []
for i, v in test.iterrows():
    if i ==0:
        decayed.append(v.val)
        continue
    d = decayed[i-1] + v.val*decay
    decayed.append(d)

test['loop_decay'] = decayed
test.head()

    val loop_decay
0   4   4.0
1   5   6.5
2   7   10.0
3   9   14.5
4   1   15.0

2 ответа

Решение

Рассмотрим векторизованную версию с cumsum() где вы кумулятивно суммируете (val * decay) с самым первым val.

Однако затем вам нужно вычесть самое первое (val * decay), так как cumsum() включает в себя:

test['loop_decay'] = (test.ix[0,'val']) + (test['val']*decay).cumsum() - (test.ix[0,'val']*decay)

Вы можете использовать pd.Series.shift() создать фрейм данных с val[i] и val[i-1], а затем применить вашу функцию к одной оси (в данном случае 1):

 # Create a series that shifts the rows by 1
 test['val2'] = test.val.shift()
 # Set the first row on the shifted series to 0
 test['val2'].ix[0] = 0
 # Apply the decay formula:
 test['loop_decay'] = test.apply(lambda x: x['val'] + x['val2'] * 0.5, axis=1)
Другие вопросы по тегам