2

全部,

我目前正在使用 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

正如你所看到的,我基本上每时每刻都在世界上生成一个新的视图并返回它。指数只是日期。

对于我尝试使用的数据量,这段代码非常慢。

你知道我怎样才能提高这个速度吗?

干杯!

4

1 回答 1

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, :]使用基本切片。它返回原始面板的视图。请注意,修改视图也会修改原始面板。

indices[first_n:cur_n + 1]是 NumPy 的 ndarray 的子类。 使用 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
于 2013-05-21T00:19:05.713 回答