使用重复索引递增 Numpy 数组

Posted

技术标签:

【中文标题】使用重复索引递增 Numpy 数组【英文标题】:Increment Numpy array with repeated indices 【发布时间】:2011-01-01 12:57:44 【问题描述】:

我有一个 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.bincountnp.unique 操作会产生相同的排序顺序是否存在风险?我是否缺少一些简单的 Numpy 操作来解决这个问题?

【问题讨论】:

请注意,numpy.zeros(6).astype('int') 最好写成 numpy.zeros(6, int)。 【参考方案1】:

在 numpy >= 1.8 中,还可以使用at 方法的加法'万能函数'('ufunc')。作为docs note:

对于加法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])

【讨论】:

这个解决方案是最优雅的 AFAIK! 我正在尝试使用矩阵执行此操作,但出现错误:arr = np.array([[1,3,5],[7,9,11]] ); lIndexes = [[0,1],[1,0],[1,2]] np.add.at(arr, lIndexes, 1) 有什么想法吗? 我建议将这个关于多维索引的新问题作为一个单独的问题发布。【参考方案2】:

如果ba 的一个小子范围,可以像这样细化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

【讨论】:

【参考方案3】:

做完之后

bbins=np.bincount(b)

为什么不这样做:

a[:len(bbins)] += bbins

(为进一步简化而编辑。)

【讨论】:

当 b 只包含几个大的 bin 数字时,这不会更慢吗? 是的,在这种情况下它会比简单的 Python 循环慢,但仍然比 OP 的代码快。我使用b = [99999, 99997, 99999]a = np.zeros(1000, 'int') 进行了快速计时测试。计时是:OP:2.5 ms,我的:495 us,简单循环:84 us。 这很好用。在我的程序中,一个简单的循环通常比较慢。谢谢。 在多维情况下有没有类似的方法来完成这个?

以上是关于使用重复索引递增 Numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

使用数组索引的numpy数组的2D索引[重复]

NumPy数组中元素的索引[重复]

如何使用索引和值迭代 1d NumPy 数组 [重复]

numpy - 返回数组中元素的第一个索引[重复]

numpy数组列表中N个最高元素的索引[重复]

如何用数组(或任何其他支持加法以便它可以偏移的东西)干净地索引numpy数组[重复]