I have a 3-dimensional coordinate. I'd like to map it to a 1-dimensional index. As I understand, one can use a pairing function to handle this in the 2-dimensional case. However, I've come up with the following naive implementation for the 3D case:
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开发者_如何学Go[x,y,z] = 0
# return 1D index
return i
This code allows me to map from the 3D point to a 1D index as the following ipython log indicates:
In [40]: xyz_to_index(m,34,56,2)
Out[40]: 345602
So now my question is, is there a better way to do this? I suppose that traversing a matrix is not the most efficient way of going about this coordinate conversion. What would you do instead?
You can implement a function ravel_index()
for NumPy arrays of arbitrary dimension:
def ravel_index(x, dims):
i = 0
for dim, j in zip(dims, x):
i *= dim
i += j
return i
This function is the inverse of the function numpy.unravel_index()
.
For your application, you can call this function as ravel_index((x, y, z), m.shape)
.
There is a general solution provided here:
Numpy interconversion between multidimensional and linear indexing
but basically if you know the shape of your multidimensional space:
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
If you know beforehand that all coordinates are in the range 0..99 you can easily calculated the index via the following function:
def xyz_to_index(x,y,z):
return ((x * 100) + y) * 100 + z
精彩评论