如何在numpy中进行分散/收集操作 [英] how to do scatter/gather operations in numpy

查看:105
本文介绍了如何在numpy中进行分散/收集操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我说我有数组:

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.

推荐答案

numpyhistogram函数是分散操作.

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中进行分散/收集操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆