pet*_*hor 15 python numpy accumulator
我正在寻找一个快速解决MATLAB的accumarray
numpy问题.的accumarray
累积,其属于同一索引的数组的元素.一个例子:
a = np.arange(1,11)
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
accmap = np.array([0,1,0,0,0,1,1,2,2,1])
Run Code Online (Sandbox Code Playgroud)
结果应该是
array([13, 25, 17])
Run Code Online (Sandbox Code Playgroud)
到目前为止我做了什么:
我已经accum
在这里的配方中尝试了这个功能很好但很慢.
accmap = np.repeat(np.arange(1000), 20)
a = np.random.randn(accmap.size)
%timeit accum(accmap, a, np.sum)
# 1 loops, best of 3: 293 ms per loop
Run Code Online (Sandbox Code Playgroud)
然后我尝试使用这里应该更快工作的解决方案,但它无法正常工作:
accum_np(accmap, a)
# array([ 1., 2., 12., 13., 17., 10.])
Run Code Online (Sandbox Code Playgroud)
是否有内置的numpy功能可以像这样积累?还是其他任何建议?
Jai*_*ime 19
使用np.bincount
与weights
可选的参数.在你的例子中,你会做:
np.bincount(accmap, weights=a)
Run Code Online (Sandbox Code Playgroud)
迟到了,但......
正如@Jamie所说,对于求和的情况,np.bincount
快速而简单.但是在更一般的情况下,对于其他ufuncs
类似的情况,maximum
可以使用该np.ufunc.at
方法.
我总结了一个要点 [见下面的链接],它将其封装在类似Matlab的界面中.它还利用了重复索引规则提供'last'
和'first'
功能,而不像Matlab的,'mean'
是合理的优化(调用accumarray
与@mean
在Matlab实在是太慢了,因为它运行的每一个组,这是愚蠢的非内置函数).
请注意,我没有特别测试过要点,但希望将来能够通过额外的功能和错误修正来更新它.
更新2015年5月/ 6月:我已经重新设计了我的实现 - 它现在作为ml31415/numpy-groupies的一部分提供,可在PyPi(pip install numpy-groupies
)上使用.基准如下(请参阅github repo获取最新值)......
function pure-py np-grouploop np-ufuncat np-optimised pandas ratio
std 1737.8ms 171.8ms no-impl 7.0ms no-impl 247.1: 24.4: - : 1.0 : -
all 1280.8ms 62.2ms 41.8ms 6.6ms 550.7ms 193.5: 9.4 : 6.3 : 1.0 : 83.2
min 1358.7ms 59.6ms 42.6ms 42.7ms 24.5ms 55.4: 2.4 : 1.7 : 1.7 : 1.0
max 1538.3ms 55.9ms 38.8ms 37.5ms 18.8ms 81.9: 3.0 : 2.1 : 2.0 : 1.0
sum 1532.8ms 62.6ms 40.6ms 1.9ms 20.4ms 808.5: 33.0: 21.4: 1.0 : 10.7
var 1756.8ms 146.2ms no-impl 6.3ms no-impl 279.1: 23.2: - : 1.0 : -
prod 1448.8ms 55.2ms 39.9ms 38.7ms 20.2ms 71.7: 2.7 : 2.0 : 1.9 : 1.0
any 1399.5ms 69.1ms 41.1ms 5.7ms 558.8ms 246.2: 12.2: 7.2 : 1.0 : 98.3
mean 1321.3ms 88.3ms no-impl 4.0ms 20.9ms 327.6: 21.9: - : 1.0 : 5.2
Python 2.7.9, Numpy 1.9.2, Win7 Core i7.
Run Code Online (Sandbox Code Playgroud)
这里我们使用100,000
统一选取的索引[0, 1000)
.具体而言,约25%的值0
(用于bool操作),其余值均匀分布[-50,25)
.计时显示10次重复.
itertools.groupby
. numpy
对值进行排序idx
,然后用于split
创建单独的数组,然后循环遍历这些数组,numpy
为每个数组运行相关的函数.numpy
ufunc.at
比它应该更慢的方法 - 在我在numpy的github repo上创建的一个问题中被删除了.numpy
索引/其他技巧来击败上述两个实现(除了min max prod
依赖ufunc.at
).pd.DataFrame({'idx':idx, 'vals':vals}).groupby('idx').sum()
等请注意,其中一些no-impl
可能是无根据的,但我还没有费心去让它们工作.
如在github解释的,accumarray
现在支持nan
-prefixed功能(例如nansum
),以及,sort
,rsort
,和array
.它也适用于多维索引.
归档时间: |
|
查看次数: |
4922 次 |
最近记录: |