我需要一个 rolling_product 函数,或者一个 expanding_product 函数。
有各种pandas
rolling_XXXX
和expanding_XXXX
函数,但我惊讶地发现没有expanding_product()
功能。
为了让事情正常进行,我一直在使用这种相当慢的替代方法
pd.expanding_apply(temp_col, lambda x : x.prod())
我的数组通常有 32,000 个元素,所以这被证明是一个瓶颈。我很想尝试 log()
、cumsum()
和 exp()
,但我想我应该在这里提问,因为可能是一个更好的解决方案。
最佳答案
我有一个更快的机制,但您需要运行一些测试以查看准确性是否足够。
这是原始的 exp/sum/log 版本:
def rolling_prod1(xs, n):
return np.exp(pd.rolling_sum(np.log(xs), n))
这是一个获取累积乘积的版本,将它移过来(用 nans 预填充),然后再将它分开。
def rolling_prod2(xs, n):
cxs = np.cumprod(xs)
nans = np.empty(n)
nans[:] = np.nan
nans[n-1] = 1.
a = np.concatenate((nans, cxs[:len(cxs)-n]))
return cxs / a
对于这个例子,两个函数返回相同的结果:
In [9]: xs
Out[9]: array([ 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [10]: rolling_prod1(xs, 3)
Out[10]: array([ nan, nan, 6., 24., 60., 120., 210., 336., 504.])
In [11]: rolling_prod2(xs, 3)
Out[11]: array([ nan, nan, 6., 24., 60., 120., 210., 336., 504.])
但是第二个版本要快得多:
In [12]: temp_col = np.random.rand(30000)
In [13]: %timeit rolling_prod1(temp_col, 3)
1000 loops, best of 3: 694 µs per loop
In [14]: %timeit rolling_prod2(temp_col, 3)
10000 loops, best of 3: 162 µs per loop
关于python - 快速 numpy rolling_product,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30384765/