Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用索引的Numpy循环_Numpy_Python 2.7 - Fatal编程技术网

使用索引的Numpy循环

使用索引的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,:]

我是一个新手,在Python2.7.2中用Numpy尝试了一些东西,但没有按预期工作,所以我想检查一下是否有一些基本的错误

我正在计算一个三角形的值(trinormals),然后使用三角形索引数组(trivertexidx)更新三角形的每个点的值(顶点法线)。作为一个循环,我正在计算:

    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)