用重复索引递增Numpy数组
我有一个Numpy数组,还有一个索引列表,我想把这些索引对应的值都加一。这个列表可能会有重复的索引,我希望加一的次数能根据每个索引出现的次数来调整。如果没有重复的索引,操作起来就很简单:
a=np.zeros(6).astype('int')
b=[3,2,5]
a[b]+=1
但是如果有重复的索引,我想出了以下的方法。
b=[3,2,5,2] # indices to increment by one each replicate
bbins=np.bincount(b)
b.sort() # sort b because bincount is sorted
incr=bbins[np.nonzero(bbins)] # create increment array
bu=np.unique(b) # sorted, unique indices (len(bu)=len(incr))
a[bu]+=incr
这样做是最好的方法吗?我是否有风险假设 np.bincount
和 np.unique
的操作结果会保持相同的排序?我是不是漏掉了什么简单的Numpy操作可以解决这个问题?
3 个回答
1
如果 b
是 a
的一个小范围,我们可以这样进一步完善 Alok 的回答:
import numpy as np
a = np.zeros( 100000, int )
b = np.array( [99999, 99997, 99999] )
blo, bhi = b.min(), b.max()
bbins = np.bincount( b - blo )
a[blo:bhi+1] += bbins
print a[blo:bhi+1] # 1 0 2
43
在numpy版本大于等于1.8时,你可以使用加法的“通用函数”(也叫ufunc)中的at
方法。正如文档中提到的:
对于加法的ufunc,这个方法相当于 a[indices] += b,不过它会对那些被多次索引的元素进行累加。
所以以你的例子为例:
a = np.zeros(6).astype('int')
b = [3, 2, 5, 2]
…然后…
np.add.at(a, b, 1)
…会让a
变成…
array([0, 0, 2, 1, 0, 1])
6
在你执行完
bbins=np.bincount(b)
之后,为什么不试试:
a[:len(bbins)] += bbins
(为了进一步简化,进行了编辑。)