如何向量化以加快Dataframe应用熊猫

时间:2020-10-02 22:06:54

标签: pandas performance numpy optimization vectorization

我有一个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)

这仍然很慢。此外,我需要对一个字典中包含的多个wts_df进行此操作,这样整个操作会花费很多时间。

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

有什么想法可以加快此类操作的速度吗?

1 个答案:

答案 0 :(得分:0)

您的问题属于“优化”类别,所以让我与您分享一些解决问题的建议。

首先,在速度方面,请始终使用%timeit来确保采用新策略可以获得更好的结果。

第二,有几种方法可以迭代数据:

  1. iterrows()一起使用-仅在数据样本较小时才使用(或者更好的是,由于速度太慢,请不要使用它)。

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

  3. Vectorizing-简而言之,您可以在整个列/数组上执行该操作,并且运算速度非常快。 优胜者!

因此,为了解决速度问题,您的策略应采用 vectorizing 的形式。所以这是它应该如何工作的; (注意 .values ):

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