แม้ว่าจะผ่านมาสักพักแล้วที่มีการถามคำถามนี้ แต่ฉันจะโพสต์คำตอบโดยหวังว่าจะช่วยใครสักคนได้
ข้อจำกัดความรับผิดชอบ:ฉันรู้ว่าโซลูชันนี้ไม่ได้มาตรฐานแต่ฉันคิดว่ามันใช้ได้ดี
import pandas as pd
import numpy as np
data = np.array([[10, 2, 10, 10],
[10, 3, 60, 100],
[np.nan] * 4,
[10, 22, 280, 250]]).T
idx = pd.date_range('20150131', end='20150203')
df = pd.DataFrame(data=data, columns=list('ABCD'), index=idx)
df
A B C D
=================================
2015-01-31 10 10 NaN 10
2015-02-01 2 3 NaN 22
2015-02-02 10 60 NaN 280
2015-02-03 10 100 NaN 250
def calculate(mul, add):
global value
value = value * mul + add
return value
value = df.loc['2015-01-31', 'D']
df.loc['2015-01-31', 'C'] = value
df.loc['2015-02-01':, 'C'] = df.loc['2015-02-01':].apply(lambda row: calculate(*row[['A', 'B']]), axis=1)
df
A B C D
=================================
2015-01-31 10 10 10 10
2015-02-01 2 3 23 22
2015-02-02 10 60 290 280
2015-02-03 10 100 3000 250
โดยพื้นฐานแล้วเราใช้ a apply
จากแพนด้าและความช่วยเหลือของตัวแปรส่วนกลางที่ติดตามค่าที่คำนวณก่อนหน้านี้
การเปรียบเทียบเวลากับการfor
วนซ้ำ:
data = np.random.random(size=(1000, 4))
idx = pd.date_range('20150131', end='20171026')
df = pd.DataFrame(data=data, columns=list('ABCD'), index=idx)
df.C = np.nan
df.loc['2015-01-31', 'C'] = df.loc['2015-01-31', 'D']
%%timeit
for i in df.loc['2015-02-01':].index.date:
df.loc[i, 'C'] = df.loc[(i - pd.DateOffset(days=1)).date(), 'C'] * df.loc[i, 'A'] + df.loc[i, 'B']
3.2 s ± 114 ms ต่อลูป (ค่าเฉลี่ย± std. dev. ของการรัน 7 ครั้ง, การวนซ้ำ 1 ครั้ง)
data = np.random.random(size=(1000, 4))
idx = pd.date_range('20150131', end='20171026')
df = pd.DataFrame(data=data, columns=list('ABCD'), index=idx)
df.C = np.nan
def calculate(mul, add):
global value
value = value * mul + add
return value
value = df.loc['2015-01-31', 'D']
df.loc['2015-01-31', 'C'] = value
%%timeit
df.loc['2015-02-01':, 'C'] = df.loc['2015-02-01':].apply(lambda row: calculate(*row[['A', 'B']]), axis=1)
1.82 วินาที± 64.4 มิลลิวินาทีต่อลูป (ค่าเฉลี่ย± std. dev ของ 7 รัน, 1 ลูปแต่ละครั้ง)
เร็วขึ้น 0.57 เท่าโดยเฉลี่ย
A
และB
?