是否有一种巧妙的方法可以将值分配给数组中的给定索引,而将平均值分配给重复的索引? 例如:
a = np.array([0, 0, 0, 0, 0])
ind = np.array([1, 1, 2, 3])
b = np.array([2, 3, 4, 5])
并且我想将数组b中的值分配给数组in中以'ind'指示的相应索引,而a [1]应该是2和3的平均值。
我可以尝试一个for循环:
hit = np.zeros_like(a)
for i in range(ind.size):
hit[ind[i]] += 1
a[ind[i]] += b[i]
a = a / hit
但是这段代码看起来很脏。有没有更好的方法来完成这项工作?
答案 0 :(得分:1)
您可以使用np.where进行此操作。
const Thing => () => {
const [tagId, setTagId] = useState(null)
const [query, setQuery] = useState('')
useEffect(() => {
if(tagId && tagId !== null) {
doSomeAjaxAndUpdateResults()
setQuery('')
}
}, [tagId])
useEffect(() => {
if(query && query !== '') {
doSomeAjaxAndUpdateResults()
}
}, [query])
}
会导致:
import numpy as np
a = np.array([0, 0, 0, 0, 0]).astype('float64')
ind = np.array([1, 1, 2, 3])
b = np.array([2, 3, 4, 5])
for i in set(ind):
a[i] = np.mean(b[np.where(ind == i)])
实际上,您正在查找In [5]: a
Out[5]: array([0. , 2.5, 4. , 5. , 0. ])
等于ind
的所有ind[index]
索引,然后获得i
中这些索引的平均值和将该均值分配给b
。希望这会有所帮助!
答案 1 :(得分:0)
这是向量化方法。实际的逻辑接近于您自己的解决方案。
n,d = (np.bincount(ind,x,a.size) for x in (b,None))
valid = d!=0
np.copyto(a,np.divide(n,d,where=valid),where=valid)
答案 2 :(得分:0)
In [56]: a = np.zeros(5)
...: hit = np.zeros_like(a)
...: for i in range(ind.size):
...: hit[ind[i]] += 1
...: a[ind[i]] += b[i]
In [57]: a
Out[57]: array([0., 5., 4., 5., 0.])
In [58]: hit
Out[58]: array([0., 2., 1., 1., 0.])
提及重复索引使我想到了.at
ufunc方法:
In [59]: a = np.zeros(5)
In [60]: a = np.zeros(5)
...: hit = np.zeros_like(a)
...: np.add.at(a,ind,b)
...: np.add.at(hit,ind,1)
In [61]: a
Out[61]: array([0., 5., 4., 5., 0.])
In [62]: hit
Out[62]: array([0., 2., 1., 1., 0.])
这没有a[ind]=b
快,但是比循环快。
np.bincount
可能会更好地完成此任务,但是add.at
值得了解和测试。
https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html
答案 3 :(得分:0)
这不一定是更干净或更快速的方法,但是我认为这是一种易于理解的替代方法:
a = [[] for _ in range(5)]
for i, x in zip(ind, b):
a[i].append(x)
[np.mean(x) if len(x) else 0 for x in a]