问题描述
让我说我有数组:
a = array((1,2,3,4,5))
indices = array((1,1,1,1))
然后我执行操作:
a[indices] += 1
结果是
array([1, 3, 3, 4, 5])
换句话说,indices
中的重复项将被忽略
in other words, the duplicates in indices
are ignored
如果我希望不要忽略重复项,则会导致:
if I wanted the duplicates not to be ignored, resulting in:
array([1, 6, 3, 4, 5])
我将如何处理?
上面的例子有些琐碎,下面正是我要做的事情:
the example above is somewhat trivial, what follows is exactly what I am trying to do:
def inflate(self,pressure):
faceforces = pressure * cross(self.verts[self.faces[:,1]]-self.verts[self.faces[:,0]], self.verts[self.faces[:,2]]-self.verts[self.faces[:,0]])
self.verts[self.faces[:,0]] += faceforces
self.verts[self.faces[:,1]] += faceforces
self.verts[self.faces[:,2]] += faceforces
def constrain_lengths(self):
vectors = self.verts[self.constraints[:,1]] - self.verts[self.constraints[:,0]]
lengths = sqrt(sum(square(vectors), axis=1))
correction = 0.5 * (vectors.T * (1 - (self.restlengths / lengths))).T
self.verts[self.constraints[:,0]] += correction
self.verts[self.constraints[:,1]] -= correction
def compute_normals(self):
facenormals = cross(self.verts[self.faces[:,1]]-self.verts[self.faces[:,0]], self.verts[self.faces[:,2]]-self.verts[self.faces[:,0]])
self.normals.fill(0)
self.normals[self.faces[:,0]] += facenormals
self.normals[self.faces[:,1]] += facenormals
self.normals[self.faces[:,2]] += facenormals
lengths = sqrt(sum(square(self.normals), axis=1))
self.normals = (self.normals.T / lengths).T
由于索引分配操作中的重复项被忽略,因此我得到了一些非常错误的结果.
Ive been getting some very buggy results as a result of duplicates being ignored in my indexed assignment operations.
推荐答案
numpy
的histogram
函数是分散操作.
a += histogram(indices, bins=a.size, range=(0, a.size))[0]
您可能需要格外小心,因为如果indices
包含整数,则较小的舍入错误可能会导致值以错误的存储区结尾.在这种情况下,请使用:
You may need to take some care because if indices
contains integers, small rounding errors could result in values ending up in the wrong bucket. In which case use:
a += histogram(indices, bins=a.size, range=(-0.5, a.size-0.5))[0]
使每个索引进入每个bin的中心.
to get each index into the centre of each bin.
更新:这行得通.但是我建议使用基于numpy.add.at
的@Eelco Hoogendoorn的答案.
Update: this works. But I recommend using @Eelco Hoogendoorn's answer based on numpy.add.at
.
这篇关于如何在numpy中进行分散/收集操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!