将三维坐标映射到一维索引

1 投票
3 回答
3335 浏览
提问于 2025-04-16 16:22

我有一个三维坐标,想把它映射成一个一维的索引。根据我的理解,在二维的情况下,可以用一种配对函数来处理这个问题。不过,我想出了一个简单的方法来处理三维的情况:

from numpy import *

# the size of the coordinate space
xn = 100
yn = 100
zn = 100

# make a 3 dimensional matrix of zeros
m = zeros((xn,yn,zn))

def xyz_to_index(m,x,y,z):
    # set a particular coordinate to 1
    m[x,y,z] = 1
    # find its index
    i = argmax(m)
    # rezero matrix
    m[x,y,z] = 0
    # return 1D index
    return i

这段代码让我可以把三维点映射成一维索引,下面的ipython日志就是证明:

In [40]: xyz_to_index(m,34,56,2)
Out[40]: 345602

所以现在我的问题是,有没有更好的方法来做到这一点?我觉得遍历一个矩阵并不是最有效的方式来进行这种坐标转换。那你会怎么做呢?

3 个回答

1

如果你事先知道所有的坐标范围是从0到99,那么你可以通过下面这个函数轻松计算出索引:

def xyz_to_index(x,y,z):
    return ((x * 100) + y) * 100 + z
2

这里提供了一个通用的解决方案:

Numpy在多维和线性索引之间的相互转换

但基本上,如果你知道你的多维空间的形状:

def ravel_index(x, dims):
    c = np.cumprod([1] + dims[::-1])[:-1][::-1]
    return np.dot(c,x)


s = [100,100,100] # shape of dims
ii = [34,56,2] # 3d index
jj = ravel_index(ii,s) # 1d index
2

你可以为任意维度的NumPy数组实现一个叫做 ravel_index() 的函数:

def ravel_index(x, dims):
    i = 0
    for dim, j in zip(dims, x):
        i *= dim
        i += j
    return i

这个函数的作用正好是 numpy.unravel_index() 函数的反向操作。

在你的应用中,你可以这样调用这个函数: ravel_index((x, y, z), m.shape)

撰写回答