使用索引的Numpy循环
我是一个新手,在Python2.7.2中用Numpy尝试了一些东西,但没有按预期工作,所以我想检查一下是否有一些基本的错误 我正在计算一个三角形的值(trinormals),然后使用三角形索引数组(trivertexidx)更新三角形的每个点的值(顶点法线)。作为一个循环,我正在计算:使用索引的Numpy循环,numpy,python-2.7,Numpy,Python 2.7,我是一个新手,在Python2.7.2中用Numpy尝试了一些东西,但没有按预期工作,所以我想检查一下是否有一些基本的错误 我正在计算一个三角形的值(trinormals),然后使用三角形索引数组(trivertexidx)更新三角形的每个点的值(顶点法线)。作为一个循环,我正在计算: for itri in range(ntriangles) : vertnormals[(trivertidx[itri,0]),:] += trinormals[itri,:]
for itri in range(ntriangles) :
vertnormals[(trivertidx[itri,0]),:] += trinormals[itri,:]
vertnormals[(trivertidx[itri,1]),:] += trinormals[itri,:]
vertnormals[(trivertidx[itri,2]),:] += trinormals[itri,:]
由于这有点慢,我认为可以修改为:
vertnormals[(trivertidx[:,0]),:] += trinormals[:,:]
vertnormals[(trivertidx[:,1]),:] += trinormals[:,:]
vertnormals[(trivertidx[:,2]),:] += trinormals[:,:]
然而,这并没有给出相同的结果。有没有其他更简单的方法来编写循环?欢迎指点。请注意,此处的目的是为vertnormals中的每个条目获取一个值,然后对结果进行归一化。如果我对您的问题理解得很好,您有
m
点,从这些点可以形成n
三角形,trivertidx
是一个形状数组(n,3)
包含范围[0,m)
,其中trivertidx[j]
是构成j
-th三角形的3个点的列表
trinormals
然后是一个形状数组(n,)
保存分配给每个三角形的值,并且您希望顶点法线
是一个形状数组(m,)
保存分配给每个点的每个三角形的值之和,该点是其顶点
如果以上是正确的,下面的示例应该说明第二个代码无法正常工作的原因:
>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
>>> a[[1,2,0,2]] += 1
>>> a
array([1, 2, 3, 3, 4])
即使位置2
中的元素在左侧显示两次,但发生的情况是相同值的两个副本已添加1
,然后增量值被复制两次到相同位置
要将此求和矢量化,您需要一个形状数组(n,m)
,其中位置[j,k]
处的值为True
如果顶点k
是三角形j
的一部分,如果不是,则为False
。您可以这样构建该数组:
trivert = np.zeros((n, m), dtype='bool')
trivert[np.arange(n).reshape(n, 1), trivertidx] = 1
一旦有了这个数组,就可以得到每个顶点的和
vertnormals = np.sum(trivert * trinormals.reshape(-1, 1), axis=0)
Numpy有一个函数
bincount
,在这种情况下非常有用。当index
的元素唯一时,下面的两行是相同的,但当index
有重复值时,这两行是不同的:
A[index] += W
A += np.bincount(index, W, minlenght=len(A))
我相信你想要第二个的行为,但是你的代码有点复杂,因为a、index和W不是1d。你可以试试这样的东西
import numpy as np
N = len(vertnormals)
for j in range(vertnormals.shape[-1]):
vertnormals[:, j] += np.bincount(trivertidx[:, 0], trinormals[:, j], minlength=N)
vertnormals[:, j] += np.bincount(trivertidx[:, 1], trinormals[:, j], minlength=N)
vertnormals[:, j] += np.bincount(trivertidx[:, 2], trinormals[:, j], minlength=N)
希望能有所帮助。很抱歉,我没有发现这个答案(不知道如何回复)。很好的解决方案,效果很好。由于我没有发现答案,所以很晚才开始讨论这个问题。对发生的情况以及第二个代码集出现问题的原因进行了很好的解释。不过解决方案有两个问题。第一个布尔数组似乎达到了极限(数组太大)对于一大组三角形和法线。第二个问题是最后一步的广播从未匹配,因为它试图广播(m,n)v(3m,1)