所有
我目前正在使用pandas中的面板来保存我的数据源。我的程序是一个简单的回测引擎。这只是为了个人娱乐,但是,我却陷入了优化之中。
使整个应用程序变慢的代码如下:
def get_generator(self):
first_n = 0
last_n = len(self.data_source.major_axis)
cur_n = 0
indices = self.data_source.major_axis
while cur_n < last_n:
yield self.data_source.ix[:, indices[first_n:cur_n + 1], :]
cur_n += 1
正如您所看到的,我基本上每时每刻都会在世界中生成一个新视图并将其返回。指数只是日期。
这段代码因我试图使用的数据量而非常慢。
你知道如何提高速度吗?
干杯!
答案 0 :(得分:2)
self.data_source.ix[:, :cur_n, :]
相当于
self.data_source.ix[:, indices[first_n:cur_n + 1], :]
但可能快2-3倍:
In [105]: import pandas as pd
In [106]: import numpy as np
In [107]: wp = pd.Panel(np.random.randn(2, 1000, 4))
In [108]: indices = wp.major_axis
In [109]: %timeit wp.ix[:, :499, :]
10000 loops, best of 3: 65.2 us per loop
In [110]: %timeit wp.ix[:, indices[0:500], :]
1000 loops, best of 3: 221 us per loop
In [114]: np.allclose(wp.ix[:, :499, :].values, wp.ix[:, indices[0:500], :].values)
Out[114]: True
self.data_source.ix[:, :cur_n, :]
使用basic slicing。它返回原始面板的视图。请注意,修改视图也会修改原始面板。
indices[first_n:cur_n + 1]
是NumPy的ndarray的子类。 Indexing with an ndarray会返回副本,而非视图。制作大型数组的副本比返回视图要慢,这可能是大部分速度增益来自的地方。但是,有时您可能需要一个副本 - 例如,当您想要修改生成的子面板而不修改原始面板时。
感谢@Jeff关于使用转置的额外想法。在我的机器上它产生了显着的改进:
In [131]: wpt = wp.transpose(1,0,2)
In [132]: %timeit wpt.ix[:499]
10000 loops, best of 3: 37.5 us per loop
In [109]: %timeit wp.ix[:, :499, :]
10000 loops, best of 3: 65.2 us per loop