使用 Python 创建 N 维网格
Creating an N-dimensional grid with Python
我正在尝试为需要和理解距离的算法创建坐标网格。我知道如何针对已知数量的维度执行此操作 - 就像 2D 一样:
x = [0,1,2]
y = [10,11,12]
z = np.zeros((3,3,2))
for i,X in enumerate(x):
for j,Y in enumerate(y):
z[i][j][0] = X
z[i][j][1] = Y
print(z)
--------------------------
array([[[ 0., 10.],
[ 0., 11.],
[ 0., 12.]],
[[ 1., 10.],
[ 1., 11.],
[ 1., 12.]],
[[ 2., 10.],
[ 2., 11.],
[ 2., 12.]]])
这很好用。我最终得到 (3,3,2) 的形状,其中 2 是该点的坐标值。我正在尝试使用它来创建概率曲面,因此我需要能够让每个点成为它自己的 "location" 值。有没有办法轻松地将其扩展到 N 维?在那里我会有未知数量的 for 循环。由于项目限制,我可以访问 Python 内置函数和 numpy,但仅此而已。
我试过 np.meshgrid() 但它导致输出形状为 (2,3,3) 并且我尝试重塑它从来没有以正确的顺序给我坐标。关于如何干净地执行此操作的任何想法?
我可以用
复制你的z
In [223]: np.stack([np.tile([x],(1,3)).reshape(3,3).T,np.tile([y],(3,1))],2)
Out[223]:
array([[[ 0, 10],
[ 0, 11],
[ 0, 12]],
[[ 1, 10],
[ 1, 11],
[ 1, 12]],
[[ 2, 10],
[ 2, 11],
[ 2, 12]]])
瓷砖碎片看起来像
In [224]: np.tile([y],(3,1))
Out[224]:
array([[10, 11, 12],
[10, 11, 12],
[10, 11, 12]])
In [225]: np.tile([x],(1,3)).reshape(3,3).T
Out[225]:
array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2]])
我也许可以清理第二个。但基本思想是以 stack
可以将它们组合成所需的 (n,n,2)
数组的方式复制输入。
一旦理解了这一点,将事物扩展到 3d 及更高版本应该就不难了。但是我还没有完全处理你的意图。
可能更简单(而且 repeat
比 tile
快):
np.stack([np.repeat(x,3).reshape(3,3), np.repeat(y,3).reshape(3,3).T], 2)
随着维度的增加,transpose
可能需要改进。
与 meshgrid
相同(它可能在内部使用 repeat
或 tile
:
In [232]: np.stack(np.meshgrid(x,y, indexing='ij'),2)
Out[232]:
array([[[ 0, 10],
[ 0, 11],
[ 0, 12]],
[[ 1, 10],
[ 1, 11],
[ 1, 12]],
[[ 2, 10],
[ 2, 11],
[ 2, 12]]])
更高维度:
In [237]: np.stack(np.meshgrid([1,2], [10,20,30], [100,200,300,400], indexing='ij'), 3).sum(axis=-1)
Out[237]:
array([[[111, 211, 311, 411],
[121, 221, 321, 421],
[131, 231, 331, 431]],
[[112, 212, 312, 412],
[122, 222, 322, 422],
[132, 232, 332, 432]]])
我正在尝试为需要和理解距离的算法创建坐标网格。我知道如何针对已知数量的维度执行此操作 - 就像 2D 一样:
x = [0,1,2]
y = [10,11,12]
z = np.zeros((3,3,2))
for i,X in enumerate(x):
for j,Y in enumerate(y):
z[i][j][0] = X
z[i][j][1] = Y
print(z)
--------------------------
array([[[ 0., 10.],
[ 0., 11.],
[ 0., 12.]],
[[ 1., 10.],
[ 1., 11.],
[ 1., 12.]],
[[ 2., 10.],
[ 2., 11.],
[ 2., 12.]]])
这很好用。我最终得到 (3,3,2) 的形状,其中 2 是该点的坐标值。我正在尝试使用它来创建概率曲面,因此我需要能够让每个点成为它自己的 "location" 值。有没有办法轻松地将其扩展到 N 维?在那里我会有未知数量的 for 循环。由于项目限制,我可以访问 Python 内置函数和 numpy,但仅此而已。
我试过 np.meshgrid() 但它导致输出形状为 (2,3,3) 并且我尝试重塑它从来没有以正确的顺序给我坐标。关于如何干净地执行此操作的任何想法?
我可以用
复制你的z
In [223]: np.stack([np.tile([x],(1,3)).reshape(3,3).T,np.tile([y],(3,1))],2)
Out[223]:
array([[[ 0, 10],
[ 0, 11],
[ 0, 12]],
[[ 1, 10],
[ 1, 11],
[ 1, 12]],
[[ 2, 10],
[ 2, 11],
[ 2, 12]]])
瓷砖碎片看起来像
In [224]: np.tile([y],(3,1))
Out[224]:
array([[10, 11, 12],
[10, 11, 12],
[10, 11, 12]])
In [225]: np.tile([x],(1,3)).reshape(3,3).T
Out[225]:
array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2]])
我也许可以清理第二个。但基本思想是以 stack
可以将它们组合成所需的 (n,n,2)
数组的方式复制输入。
一旦理解了这一点,将事物扩展到 3d 及更高版本应该就不难了。但是我还没有完全处理你的意图。
可能更简单(而且 repeat
比 tile
快):
np.stack([np.repeat(x,3).reshape(3,3), np.repeat(y,3).reshape(3,3).T], 2)
随着维度的增加,transpose
可能需要改进。
与 meshgrid
相同(它可能在内部使用 repeat
或 tile
:
In [232]: np.stack(np.meshgrid(x,y, indexing='ij'),2)
Out[232]:
array([[[ 0, 10],
[ 0, 11],
[ 0, 12]],
[[ 1, 10],
[ 1, 11],
[ 1, 12]],
[[ 2, 10],
[ 2, 11],
[ 2, 12]]])
更高维度:
In [237]: np.stack(np.meshgrid([1,2], [10,20,30], [100,200,300,400], indexing='ij'), 3).sum(axis=-1)
Out[237]:
array([[[111, 211, 311, 411],
[121, 221, 321, 421],
[131, 231, 331, 431]],
[[112, 212, 312, 412],
[122, 222, 322, 422],
[132, 232, 332, 432]]])