Python Pandas cumsum dengan pergeseran n

Oct 01 2020

Saya ingin tahu apakah ada cara yang efisien (menghindari loop) untuk melakukan a serie.cumsum()tetapi dengan pergeseran n .

Dengan cara yang sama Anda dapat melihat serie.cumsum()seperti kebalikan dari serie.diff(1)Saya mencari kebalikan dari diff(n)(Saya tahu bahwa untuk pembalikan yang tepat Anda memerlukan nilai awal tetapi untuk kesederhanaan saya mengabaikannya di sini) yang bisa dipanggilcumsum_shift

Lebih eksplisit mengimplementasikannya dengan for loop (yang ingin saya hindari):

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

Kode dengan shift = 1ini persis sama dengan yang dilakukan s.cumsum()metode pandas tetapi tentu saja metode pandas melakukannya dalam kode C (saya kira) jadi jauh lebih cepat (tentu saja Anda harus selalu menggunakan s.cumsum()metode pandas dan tidak mengimplementasikannya sendiri dengan untuk loop).

Pertanyaan saya kemudian adalah Apa yang akan menjadi cara melakukan cumsum_shiftmenghindari perulangan for dengan metode pandas?

Edit 1

Menambahkan contoh input dan output

Jika Anda menyebutnya dengan:

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

Dengan masukan ini, keluaran cumsum_shift(s.diff(3), shift = 3, init_values = [1,2,3])lagi adalah seri aslinya s. Perhatikan pergeseran 3, ini dengan hanya cumsum()misalnya s.diff(3).cumsum()tidak akan memulihkan aslinya 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

Tapi izinkan saya menekankan bahwa nilai awal bukanlah masalah besar, perbedaan konstan bukanlah masalah. Saya ingin tahu bagaimana melakukan cumsum dari seri differenced bergeser tanpa harus menggunakan for loop

Dengan cara yang sama jika Anda melakukan a diff()dan kemudian a cumsum()Anda mengembalikan yang asli ke nilai awal:

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

Saya ingin tahu apakah ada cara cerdas untuk melakukan sesuatu seperti s.diff(n).cumsum(n)itu yang mengembalikan sesuatu yang benar hingga beberapa nilai awal yang konstan.

EDIT 2 - Membalikkan Moving Average

Memikirkan penerapan "cumsum bergeser" Saya menemukan pertanyaan lain ini di SO tentang bagaimana membalikkan rata-rata bergerak yang telah saya jawab menggunakan cumsum_shiftfungsi saya dan saya pikir itu menjelaskan lebih lanjut apa yang saya tanyakan di sini

Jawaban

1 Elif Oct 01 2020 at 21:34

Anda dapat menggunakan metode pandas rolling.sum () di antara dengan sum:

s.rolling(shift).sum()

Namun Anda mungkin ingin mengisi nilai NaN sampai bergeser dengan df asli.