使用Numba高效处理pandas DataFrame时间序列的方法
我有一个包含1,500,000行的数据表,这些数据是我从QuantQuote.com购买的每分钟股票市场数据(包括开盘价、最高价、最低价、收盘价和成交量)。我想进行一些自制的股票交易策略回测。但是,直接用Python代码处理这些交易数据太慢了,所以我想试试用numba来加速处理。不过,问题是numba似乎不能和pandas函数一起使用。
在谷歌搜索中,我发现关于numba和pandas结合使用的信息非常少,这让我怀疑自己是不是考虑错了。
我的环境是Numba 0.13.0-1,Pandas 0.13.1-1,Windows 7,MS VS2013配合PTVS,Python 2.7,以及Enthought Canopy。
我现有的Python+Pandas代码大致结构如下:
- 计算“指标”列(使用pd.ewma、pd.rolling_max、pd.rolling_min等函数)
- 计算“事件”列,用于预设的事件,比如移动平均线交叉、新高等。
然后我使用DataFrame.iterrows来处理这个数据表。
我尝试了各种优化方法,但速度还是不够快,而且这些优化还导致了一些错误。
我想用numba来处理这些行数据。有没有推荐的方法来实现这个?
因为我的数据表实际上只是一个浮点数的矩形,我考虑使用DataFrame.values来访问数据,然后写一系列使用numba的函数来处理这些行。但这样做会丢失所有的时间戳,我觉得这不是一个可逆的操作。我不确定从DataFrame.values得到的值矩阵是否一定不是数据的副本。
任何帮助都非常感谢。
2 个回答
简单明了的回答是,在使用 pip 安装时,Pandas 不支持 numba(https://numba.pydata.org/numba-doc/dev/reference/numpysupported.html),而且 cudf 的支持也不太好,所以你可能会遇到错误。
Numba 是一个能理解 NumPy 的即时编译器。你可以把 NumPy 数组作为参数传给用 Numba 编译的函数,但不能直接用 Pandas 的系列数据。
截至 2017 年 6 月 27 日,你唯一的选择是使用 Pandas 系列中的值,这些值其实是 NumPy 数组。
另外,你问这些值是否“保证不是数据的副本”。它们确实不是副本,你可以通过以下方式验证:
import pandas
df = pandas.DataFrame([0, 1, 2, 3])
df.values[2] = 8
print(df) # Should show you the value `8`
在我看来,Numba 是处理市场数据的一个很棒(如果不是最好的)方法,特别是如果你只想用 Python。如果你想获得显著的性能提升,确保使用 @numba.jit(nopython=True)
(注意,这样做会让你不能在 JIT 编译的函数中使用字典和其他 Python 类型,但会让代码运行得更快)。
要注意的是,你正在使用的一些指标可能在 Pandas 中已经有高效的实现,所以可以考虑先用 Pandas 计算这些指标,然后把值(NumPy 数组)传给你的 Numba 回测函数。