Python Pandas cumsum พร้อม shift ของ n

Oct 01 2020

ฉันต้องการทราบว่ามีวิธีที่มีประสิทธิภาพ (หลีกเลี่ยงการวนซ้ำ) ในการทำ a serie.cumsum()แต่มีการเปลี่ยน nหรือไม่

เช่นเดียวกับที่คุณเห็นserie.cumsum()เช่นการผกผันของserie.diff(1)ฉันกำลังมองหาค่าผกผันdiff(n)(ฉันรู้ว่าสำหรับการผกผันที่เหมาะสมคุณต้องมีค่าเริ่มต้น แต่เพื่อความง่ายฉันไม่สนใจที่นี่) ซึ่งอาจเรียกได้ว่าcumsum_shift

การนำไปใช้อย่างชัดเจนยิ่งขึ้นด้วยfor loop (ซึ่งฉันต้องการหลีกเลี่ยง):

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()วิธีการของแพนด้า แต่แน่นอนว่าวิธีการของแพนด้าทำในรหัส C (ฉันเดา) ดังนั้นจึงเร็วกว่ามาก (แน่นอนว่าคุณควรใช้s.cumsum()วิธีการแพนด้าเสมอและอย่าใช้มันด้วยตัวเองด้วยสำหรับ วน).

คำถามของฉันคืออะไรคือวิธีcumsum_shiftหลีกเลี่ยงการวนซ้ำด้วยวิธีแพนด้า?

แก้ไข 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

ด้วยการป้อนข้อมูลนี้ ouput ของอีกชุดเดิม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

แต่ขอย้ำว่าค่าเริ่มต้นไม่ใช่เรื่องใหญ่ความแตกต่างคงที่ไม่ใช่ปัญหา ฉันต้องการทราบวิธีดำเนินการ cumsum ของซีรีย์ที่แตกต่างกันโดยไม่ต้องใช้ for loop

เช่นเดียวกับที่ถ้าคุณทำ a diff()แล้ว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 - ย้อนกลับค่าเฉลี่ยเคลื่อนที่

เมื่อนึกถึงแอปพลิเคชันของ "shifted cumsum" ฉันพบคำถามอื่นนี้ใน SOเกี่ยวกับวิธีการย้อนกลับค่าเฉลี่ยเคลื่อนที่ที่ฉันตอบโดยใช้cumsum_shiftฟังก์ชันของฉันและฉันคิดว่ามันให้ความกระจ่างมากขึ้นในสิ่งที่ฉันกำลังถามที่นี่

คำตอบ

1 Elif Oct 01 2020 at 21:34

คุณสามารถใช้วิธีการของแพนด้าrolling.sum ()ร่วมกับผลรวม:

s.rolling(shift).sum()

อย่างไรก็ตามคุณอาจต้องการเติมค่า NaN จนกว่าจะเปลี่ยนด้วย df เดิม