Python Pandas cumsum со сдвигом n

Oct 01 2020

Я хотел бы знать, есть ли эффективный способ (избегая циклов for) сделать, serie.cumsum()но со сдвигом n .

Точно так же, как вы можете видеть serie.cumsum()обратное, serie.diff(1)я ищу обратное diff(n)(я знаю, что для правильного обратного вам нужны начальные значения, но для простоты я игнорирую их здесь), который можно назватьcumsum_shift

Более явная реализация его с помощью цикла for (чего я бы хотел избежать):

def cumsum_shift(s, shift = 1, init_values = [0]):
    s_cumsum = pd.Series(np.zeros(len(s)))
    for i in range(shift):
        s_cumsum.iloc[i] = init_values[i]
    for i in range(shift,len(s)):
        s_cumsum.iloc[i] = s_cumsum.iloc[i-shift] + s.iloc[i]
    return s_cumsum

Этот код shift = 1точно такой же, что и s.cumsum()метод pandas, но, конечно же, метод pandas делает это в коде C (я думаю), поэтому он намного быстрее (конечно, вы всегда должны использовать s.cumsum()метод pandas, а не реализовывать его самостоятельно с помощью for петля).

Тогда мой вопрос: как бы cumsum_shiftизбежать цикла for с помощью методов pandas?

Редактировать 1

Добавление примера ввода и вывода

Если вы позвоните с помощью:

s = pd.Series([1,10,100,2,20,200,5,50,500])
s.diff(3)
out[26] 0      NaN
        1      NaN
        2      NaN
        3      1.0
        4     10.0
        5    100.0
        6      3.0
        7     30.0
        8    300.0
        dtype: float64

С этим вводом на выходе cumsum_shift(s.diff(3), shift = 3, init_values = [1,2,3])снова будет исходная серия s. Обратите внимание на сдвиг на 3, это, cumsum()например s.diff(3).cumsum(), не восстановит оригинал s:

cumsum_shift(s.diff(3), shift = 3, init_values= [1,10,100])
out[27]
0      1.0
1     10.0
2    100.0
3      2.0
4     20.0
5    200.0
6      5.0
7     50.0
8    500.0
dtype: float64

Но позвольте мне подчеркнуть, что начальные значения не имеют большого значения, постоянная разница - не проблема. Я хотел бы знать, как выполнить суммирование смещенной разностной серии без использования цикла for

Таким же образом, если вы выполните a, diff()а затем a, cumsum()вы вернете исходное значение до исходного значения:

s = pd.Series([1,10,100,2,20,200,5,50,500])
s.diff().cumsum()
out[28]
0      NaN
1      9.0
2     99.0
3      1.0
4     19.0
5    199.0
6      4.0
7     49.0
8    499.0
dtype: float64

Я хотел бы знать, есть ли какой-нибудь умный способ сделать что-то подобное s.diff(n).cumsum(n), вернув что-то правильное до некоторых постоянных начальных значений.

РЕДАКТИРОВАТЬ 2 - Обратное скользящее среднее

Думая о применении «сдвинутой кончи», я нашел другой вопрос в SO о том, как перевернуть скользящую среднюю, на который я ответил, используя свою cumsum_shiftфункцию, и я думаю, что он более разъясняет то, о чем я спрашиваю здесь

Ответы

1 Elif Oct 01 2020 at 21:34

Вы можете использовать метод pandas Rolling.sum () вместе с sum:

s.rolling(shift).sum()

Однако вы можете захотеть заполнить значения NaN до сдвига с исходным df.