我有一个相当复杂的预测代码,每列使用wls超过20列和数百万数据。现在我使用iterrow循环日期,然后根据这些日期中的日期和值,提取不同大小的数据进行计算。在我的制作中运行需要几个小时,我将代码简化为以下内容:
import pandas as pd
import numpy as np
from datetime import timedelta
df=pd.DataFrame(np.random.randn(1000,2), columns=list('AB'))
df['dte'] = pd.date_range('9/1/2014', periods=1000, freq='D')
def calculateC(A, dte):
if A>0: #based on values has different cutoff length for trend prediction
depth=10
else:
depth=20
lastyear=(dte-timedelta(days=365))
df2=df[df.dte<lastyear].head(depth) #use last year same date data for basis of prediction
return df2.B.mean() #uses WLS in my model but for simplification replace with mean
for index, row in df.iterrows():
if index>365:
df.loc[index,'C']=calculateC(row.A, row.dte)
我读到iterrow是主要原因,因为它不是使用Pandas的有效方法,我应该使用vector方法。但是,我似乎无法根据条件(日期,不同长度和值范围)找到一种矢量方法。有办法吗?
答案 0 :(得分:2)
我有好消息和坏消息。好消息是我有一些矢量化的速度大约快300倍,但坏消息是我不能完全复制你的结果。但我认为您应该能够使用此处的原则来大大加快代码速度,即使此代码实际上并未实际复制您的结果。
df['result'] = np.where( df['A'] > 0,
df.shift(365).rolling(10).B.mean(),
df.shift(365).rolling(20).B.mean() )
代码的难度(慢)部分是这样的:
df2=df[df.dte<lastyear].head(depth)
但是,只要您的日期相隔365天,您就可以使用这样的代码,它是矢量化的,速度更快:
df.shift(365).rolling(10).B.mean()
shift(365)
取代df.dte < lastyear
,rolling().mean()
取代head().mean()
。它会更快,使用更少的内存。
实际上,即使您的日期不是完全正常的,您也可以重新采样并使这种方式起作用。或者,在某种程度上,如果您将日期作为索引,则可以根据频率而不是行来进行转换(例如,转换365天,即使不是365行)。制作&#39; dte&#39;可能是一个好主意。你的索引无论如何。
答案 1 :(得分:0)
我会尝试pandas.DataFrame.apply(func,axis = 1)
def calculateC2(row):
if row.name >365: # row.name is the index of the row
if row.A >0: #based on values has different cutoff length for trend prediction
depth=10
else:
depth=20
lastyear=(row.dte-timedelta(days=365))
df2=df[df.dte<lastyear].B.head(depth) #use last year same date data for basis of prediction
print row.name,np.mean(df2) #uses WLS in my model but for simplification replace with mean
df.apply(calculateC2,axis=1)