我面临着熊猫滚动(扩展)10年历史记录zscore计算的性能问题。太慢了 对于最近的单个zscore,需要17秒 要计算整个历史记录,大约需要30分钟。(我已经将该历史记录重新采样为每周一次,以缩减为总记录。
如果您有任何建议加快我的lastz功能,请随时分享您的想法。
这是详细信息。 1。数据集。 10年的库存记录,已对其进行重新采样以平衡大小和准确性。 总大小为(207376,8) 涵盖了过去10年的约500个指数数据。这是示例:
> Close PB1 PB2 PE1 PE2 TurnoverValue TurnoverVol ROE
>ticker tradeDate
>000001 2007-01-07 2678.526489 3.38135 2.87570 34.423700 61.361549 7.703712e+10 1.131558e+10 0.098227
>2007-01-14 2755.759814 3.45878 3.09090 35.209019 66.407800 7.897185e+10 1.116473e+10 0.098236
>2007-01-21 2796.761572 3.49394 3.31458 35.561800 70.449658 8.416415e+10 1.129387e+10 0.098250
功能需要加速:
ts_start=pd.to_date("20180831")
@numba.jit
def lastz(x):
if x.index.max()[1]<ts_start:
return np.nan
else:
freedom = 1 # it is sample, so the sample std degree of freedome should not be 0 but 1
nlimit_interpolate = int(len(x)/100) #1% fill allowed
#print(nlimit_interpolate, len(x))
x=x.interpolate(limit=nlimit_interpolate+1 ) # plus 1 in case of 0 or minus
x=x.loc[x.notnull()]
Arry=x.values
zscore = stats.zmap(Arry[-1],Arry,ddof=freedom)
return zscore
weekly = weekly.sort_index()
%prun -s cumtime result = weekly.groupby(level="ticker").agg(lastz)
这是单个调用的修剪结果: 在17.183秒内进行13447048个函数调用(13340521个原始调用)
排序依据:累计时间
> ncalls tottime percall cumtime percall
> filename:lineno(function)
> 1 0.000 0.000 17.183 17.183 {built-in method builtins.exec}
> 1 0.000 0.000 17.183 17.183 <string>:1(<module>)
> 1 0.000 0.000 17.176 17.176 groupby.py:4652(aggregate)
> 1 0.000 0.000 17.176 17.176 groupby.py:4086(aggregate)
> 1 0.000 0.000 17.176 17.176 base.py:562(_aggregate_multiple_funcs)
> 16/8 0.000 0.000 17.171 2.146 groupby.py:3471(aggregate)
> 8 0.000 0.000 17.171 2.146 groupby.py:3513(_aggregate_multiple_funcs)
> 8 0.000 0.000 17.147 2.143 groupby.py:1060(_python_agg_general)
> 8 0.000 0.000 17.145 2.143 groupby.py:2668(agg_series)
> 8 0.172 0.022 17.145 2.143 groupby.py:2693(_aggregate_series_pure_python)
> 4400 0.066 0.000 15.762 0.004 groupby.py:1062(<lambda>)
> 4400 0.162 0.000 14.255 0.003 <ipython-input-10-fdb784c8abd8>:15(lastz)
> 4400 0.035 0.000 8.982 0.002 base.py:807(max)
> 4400 0.070 0.000 7.955 0.002 multi.py:807(values)
> 4400 0.017 0.000 6.406 0.001 datetimes.py:976(astype)
> 4400 0.007 0.000 6.316 0.001 datetimelike.py:1130(astype)
> 4400 0.030 0.000 6.301 0.001 datetimelike.py:368(_box_values_as_index)
> 4400 0.009 0.000 5.613 0.001 datetimelike.py:362(_box_values)
> 4400 0.860 0.000 5.602 0.001 {pandas._libs.lib.map_infer} 1659008 4.278 0.000 4.741
> 0.000 datetimes.py:606(<lambda>)
> 4328 0.096 0.000 1.774 0.000 generic.py:5980(interpolate)
> 4336 0.015 0.000 1.696 0.000 indexing.py:1463(__getitem__)
> 4328 0.028 0.000 1.675 0.000 indexing.py:1854(_getitem_axis)
我想知道数据时间比较调用的频率是否太高,是否有更好的方法跳过那些计算结果。我每周计算结果。因此,上周的数据已经不需要再计算了。 index.max()[1]用于检查数据集是否晚于某天。如果是较新的,则计算得出,否则,只需返回nan。
如果我使用滚动或展开模式,则需要半小时或2个小时才能得到结果。
赞赏任何想法或线索以加快该功能。
答案 0 :(得分:0)
timeit result of different index method speed in pandas multiindex
我将索引选择方法更改为每次单次计算节省6秒。
但是总运行时间仍然太长,无法接受。需要您的线索来对其进行优化。