Numpy 根据数组中的元素值对它们求和
- 2025-03-06 08:52:00
- admin 原创
- 69
问题描述:
我有未排序的索引数组:
i = np.array([1,5,2,6,4,3,6,7,4,3,2])
我还有一个相同长度的值数组:
v = np.array([2,5,2,3,4,1,2,1,6,4,2])
我有一个包含所需值零的数组:
d = np.zeros(10)
现在我想根据 i 中的索引将元素添加到 v 的 d 值中。
如果我使用普通的 Python 来做的话,我会这样做:
for index,value in enumerate(v):
idx = i[index]
d[idx] += v[index]
它很丑而且效率低下。我该如何改变它?
解决方案 1:
np.add.at(d, i, v)
您可能认为d[i] += v
这种方法可行,但如果您尝试以这种方式对同一单元格进行多次添加,则其中一个会覆盖其他。该ufunc.at
方法可避免这些问题。
解决方案 2:
我们可以使用np.bincount
据说非常有效的方法来进行这种累积加权计数,所以这里有一个 -
counts = np.bincount(i,v)
d[:counts.size] = counts
或者,使用minlength
输入参数,对于一般情况,d
可以是任何数组,并且我们想要添加到其中 -
d += np.bincount(i,v,minlength=d.size).astype(d.dtype, copy=False)
运行时测试
本节np.add.at
将列出的方法other post
与np.bincount
本文前面列出的方法进行比较。
In [61]: def bincount_based(d,i,v):
...: counts = np.bincount(i,v)
...: d[:counts.size] = counts
...:
...: def add_at_based(d,i,v):
...: np.add.at(d, i, v)
...:
In [62]: # Inputs (random numbers)
...: N = 10000
...: i = np.random.randint(0,1000,(N))
...: v = np.random.randint(0,1000,(N))
...:
...: # Setup output arrays for two approaches
...: M = 12000
...: d1 = np.zeros(M)
...: d2 = np.zeros(M)
...:
In [63]: bincount_based(d1,i,v) # Run approaches
...: add_at_based(d2,i,v)
...:
In [64]: np.allclose(d1,d2) # Verify outputs
Out[64]: True
In [67]: # Setup output arrays for two approaches again for timing
...: M = 12000
...: d1 = np.zeros(M)
...: d2 = np.zeros(M)
...:
In [68]: %timeit add_at_based(d2,i,v)
1000 loops, best of 3: 1.83 ms per loop
In [69]: %timeit bincount_based(d1,i,v)
10000 loops, best of 3: 52.7 µs per loop
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD