【问题标题】:How to vectorize to speed up Dataframe apply pandas如何矢量化以加快 Dataframe 应用 pandas
【发布时间】:2021-01-18 13:21:39
【问题描述】:

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

任何想法如何加快此类操作?

【问题讨论】:

  • 感谢您分享您的意见。您能否在问题中分享您的预期输出?此外,您有两个不在问题中的输入数据框,因此任何人都很难回答。
  • 我正在投票结束这个问题,因为正在寻求指导以提高性能的工作代码问题更适合Code Review

标签: pandas performance numpy optimization vectorization


【解决方案1】:

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

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

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

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

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

  3. Vectorizing --简单地说,您对整个列/数组执行操作,并且速度非常快。 获胜者!

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

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

【讨论】:

  • 谢谢,这就是我用矢量化标记我的问题的确切原因。现在还添加了优化。但问题是在这种情况下如何向量化。看起来并不那么简单。
  • @dayum 不要尝试使用 for 循环中呈现的业务逻辑执行 my_function。从一个简单的虚拟结果开始,然后根据您的需要(整个业务逻辑)进行处理。此外,由于我们没有您的数据,因此很难通过矢量化获得正确的结果
猜你喜欢
  • 2023-03-20
  • 2015-01-02
  • 1970-01-01
  • 2017-09-26
  • 2021-02-10
  • 2020-08-02
  • 1970-01-01
  • 2020-12-15
  • 2019-12-21
相关资源
最近更新 更多