我有一个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()}
有什么想法可以加快此类操作的速度吗?
答案 0 :(得分:0)
您的问题属于“优化”类别,所以让我与您分享一些解决问题的建议。
首先,在速度方面,请始终使用%timeit来确保采用新策略可以获得更好的结果。
第二,有几种方法可以迭代数据:
与iterrows()
一起使用-仅在数据样本较小时才使用(或者更好的是,由于速度太慢,请不要使用它)。
使用apply
-更好的替代迭代并且效率更高,但是当数据集很大(如您的示例)时,可能会出现延迟问题。
Vectorizing
-简而言之,您可以在整个列/数组上执行该操作,并且运算速度非常快。 优胜者!
因此,为了解决速度问题,您的策略应采用 vectorizing 的形式。所以这是它应该如何工作的; (注意 .values ):
df['new_column'] = my_function(df['column_1'].values, df['column_2'].values...)
,您会注意到超快的结果。