Jas*_*rgh 4 python numpy python-2.7 pandas
我需要一个rolling_product 函数,或者一个expanding_product 函数。
有各种pandas rolling_XXXX和expanding_XXXX功能,但我很惊讶地发现缺少的expanding_product()功能。
为了让事情顺利进行,我一直在使用这种相当缓慢的替代方案
pd.expanding_apply(temp_col, lambda x : x.prod())
Run Code Online (Sandbox Code Playgroud)
我的数组通常有 32,000 个元素,所以这被证明是一个瓶颈。我很想尝试log(), cumsum(), 和exp(),但我想我应该在这里问一下,因为可能有更好的解决方案。
我有一个更快的机制,但您需要运行一些测试来查看准确性是否足够。
这是原始的 exp/sum/log 版本:
def rolling_prod1(xs, n):
return np.exp(pd.rolling_sum(np.log(xs), n))
Run Code Online (Sandbox Code Playgroud)
这是一个版本,它采用累积乘积,将其转移(用 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
Run Code Online (Sandbox Code Playgroud)
对于此示例,两个函数都返回相同的结果:
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.])
Run Code Online (Sandbox Code Playgroud)
但是第二个版本要快得多:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1605 次 |
| 最近记录: |