Python Numpy einsum()用于旋转网格网格

Python Numpy einsum()用于旋转网格网格,python,numpy,numpy-einsum,Python,Numpy,Numpy Einsum,我有一组使用meshgrid()生成的三维坐标。我希望能够围绕3个轴旋转这些 我尝试分解网格并在每个点上旋转,但是网格太大,我的内存不足 使用einsum()在2d中解决此问题,但在将其扩展到3d时,我无法确定字符串格式 我已经阅读了其他几页关于einsum()及其格式字符串的内容,但还没有弄清楚 编辑: 我称我的网格轴为X、Y和Z,每一个都是形状(213、48、37)。另外,当我试图将结果放回网格时,实际的内存错误出现了 当我尝试“分解”它进行逐点旋转时,我使用了以下功能: def mg2co

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

我尝试分解网格并在每个点上旋转,但是网格太大,我的内存不足

使用einsum()在2d中解决此问题,但在将其扩展到3d时,我无法确定字符串格式

我已经阅读了其他几页关于einsum()及其格式字符串的内容,但还没有弄清楚

编辑:

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

当我尝试“分解”它进行逐点旋转时,我使用了以下功能:

def mg2coords(X, Y, Z):
    return np.vstack([X.ravel(), Y.ravel(), Z.ravel()]).T
我将结果循环如下:

def rotz(angle, point):
    rad = np.radians(angle)
    sin = np.sin(rad)
    cos = np.cos(rad)
    rot = [[cos, -sin, 0],
           [sin,  cos, 0],
           [0, 0, 1]]

    return np.dot(rot, point)

旋转后,我将使用要插值的点。

处理您的定义:

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
sum
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
类似于
1
2

或者,我可以将
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

网格和旋转矩阵的尺寸是多少?“解开”是指你在链接中尝试了第二个答案吗?如果有更多的信息,我可以帮助您使用
einsum
,但我怀疑它是否更节省内存。Stll我们可以试试。@hpaulj,更具体地说,我试图从点重新创建网格网格。因为这组点旋转了15度,我打赌这会让网格变得疯狂。我现在正在研究是否可以使用点本身对3d数据进行插值。我发现我可以使用我在原始帖子中提到的循环旋转的点进行插值,而无需将它们放入网格中。但我仍然对您关于如何使用einsum()进行3d旋转的想法非常感兴趣。谢谢我特别感谢您对代码所做的细微更改,例如返回矩阵而不是旋转坐标,从而节省了许多计算。还有列表理解。。。我总是忘记在我的代码中包含这些。感谢您展示了4d的扩展,我可能需要使用齐次坐标进行变换。