Numpy einsum()用于旋转网格

时间:2015-08-04 18:36:13

标签: python numpy numpy-einsum

我有一组使用meshgrid()生成的3d坐标。我希望能够绕3轴旋转这些。

我尝试解开网格网并在每个点上进行旋转,但是网格网格很大,而且内存不足。

This question使用einsum()在2d中解决了这个问题,但在将其扩展为3d时,我无法弄清楚字符串格式。

我已经阅读了其他几个关于einsum()及其格式字符串的页面,但还没有能够弄明白。

修改

我称我的网格轴X,Y和Z,每个都是形状(213,48,37)。此外,当我试图将结果放回到meshgrid中时,出现了实际的内存错误。

当我试图解开'它逐点旋转我使用了以下功能:

SHA256.Create("System.Security.Cryptography.SHA256Cng")

我用以下内容循环结果:

def mg2coords(X, Y, Z):
    return np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T

旋转后,我将使用点进行插值。

1 个答案:

答案 0 :(得分:4)

使用您的定义:

In [840]: def mg2coords(X, Y, Z):
        return np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T

In [841]: def rotz(angle):
        rad = np.radians(angle)
        sin = np.sin(rad)
        cos = np.cos(rad)
        rot = [[cos, -sin, 0],
               [sin,  cos, 0],
               [0, 0, 1]]
        return np.array(rot)
        # just to the rotation matrix

定义一个示例网格:

In [842]: X,Y,Z=np.meshgrid([0,1,2],[0,1,2,3],[0,1,2],indexing='ij')    
In [843]: xyz=mg2coords(X,Y,Z)

逐行旋转:

In [844]: xyz1=np.array([np.dot(rot,i) for i in xyz])

等效einsum逐行计算:

In [845]: xyz2=np.einsum('ij,kj->ki',rot,xyz)

他们匹配:

In [846]: np.allclose(xyz2,xyz1)
Out[846]: True

或者,我可以将3个阵列收集到一个4d阵列中,然后用einsum旋转它。这里np.array会在开头添加维度。因此,dot总和j维度为第1,数组的3d如下:

In [871]: XYZ=np.array((X,Y,Z))
In [872]: XYZ2=np.einsum('ij,jabc->iabc',rot,XYZ)

In [873]: np.allclose(xyz2[:,0], XYZ2[0,...].ravel())
Out[873]: True

12相似。

或者我可以将XYZ2分成3个组件数组:

In [882]: X2,Y2,Z2 = XYZ2
In [883]: np.allclose(X2,xyz2[:,0].reshape(X.shape))
Out[883]: True

如果您想向另一个方向旋转,请使用ji代替ij,即使用rot.T