如何矢量化加快数据帧应用熊猫



我有一个tXn(5000 X 100(数据帧wts_df,

wts_df.tail().iloc[:, 0:6]
Out[71]: 
B         C         H         L         R         T  
2020-09-25  0.038746  0.033689 -0.047835 -0.002641  0.009501 -0.030689   
2020-09-28  0.038483  0.033189 -0.061742  0.001199  0.009490 -0.028370   
2020-09-29  0.038620  0.034957 -0.031341  0.006179  0.007815 -0.027317   
2020-09-30  0.038610  0.034902 -0.014271  0.004512  0.007836 -0.024672   
2020-10-01  0.038790  0.029937 -0.044198 -0.008415  0.008347 -0.030980   

以及两个类似的txn数据帧vol_df和rx_df(相同的索引和列(。现在我们可以使用

rx_df = wts_df.applymap(lambda x: np.random.rand())
vol_df = wts_df.applymap(lambda x: np.random.rand())

我需要这样做(简化(:

for date in wts_df.index:
wts = wts_df.loc[date]   # is a vector now 1Xn
# mutliply all entries of rx_df and vol_df until this date by these wts, and sum across columns
rx = rx_df.truncate(after=date)   # still a dataframe but truncated at a given date, kXn
vol = vol_df_df.truncate(after=date)   
wtd_rx = (wts * rx).sum(1)   # so a vector kX1
wtd_vol = (wts * vol).sum(1)   
# take ratio
rx_vol = rx / vol
rate[date] = rx_vol.tail(20).std()

所以利率看起来像这个

pd.Series(rate).tail()
Out[71]: 
rate         
2020-09-25  0.0546   
2020-09-28  0.0383  
2020-09-29  0.0920    
2020-09-30  0.0510  
2020-10-01  0.0890 

上面的循环很慢,所以我尝试了这个:

def rate_calc(wts, date, rx_df=rx_df, vol_df=vol_df):
wtd_rx = (rx_df * wts).sum(1) 
wtd_vol = (vol_df * wts).sum(1)
rx_vol = wtd_rx / wtd_vol
rate = rx_vol.truncate(after=date).tail(20).std() 
return rate
rates = wts_df.apply(lambda x: rate_calc(x, x.name), axis=1)

这仍然非常缓慢。此外,我需要对dict中包含的多个wts_df执行此操作,因此总操作需要花费大量时间。

rates = {key: val.apply(lambda x: rate_calc(x, x.name), axis=1) for key, val in wts_df_dict.iteritems()}

有什么想法可以加快这样的行动吗?

您的问题属于"优化"类别,请允许我与您分享一些解决您问题的建议。

首先,当谈到速度时,总是使用%timeit,以确保您使用新策略获得更好的结果。

其次,迭代数据的方法很少:

  1. 使用iterrows()——仅在数据样本较小时使用它(或者更好的是,尽量不要使用它,因为它太慢(。

  2. 使用apply——更好地替代迭代行,效率更高,但当数据集很大时(如您的示例(,可能会出现延迟问题。

  3. Vectorizing——简单地说,您可以对整个列/数组执行操作,而且操作速度非常快获胜者

因此,为了解决速度问题,您的策略应该采用矢量化的形式。以下是它应该如何工作;(注意.值(:

df['new_column'] = my_function(df['column_1'].values, df['column_2'].values...),你会注意到一个超快速的结果。

最新更新