Python 如何重新索引3d numpy数组

Python 如何重新索引3d numpy数组,python,arrays,numpy,indexing,Python,Arrays,Numpy,Indexing,假设我们有一个3D阵列,如: array=np.arange(8).重塑(2,2,2) new_array=np.zero((2,2,2)) 假设我们的数组有一些新的随机x,y,z索引 x,y,z = np.meshgrid(array, array, array) 重新索引阵列的最快方法是什么 这里给出了一个简单的解决方案: for x in range(0, 3): for y in range(0, 3): for z in range(0, 3):

假设我们有一个3D阵列,如:

array=np.arange(8).重塑(2,2,2)
new_array=np.zero((2,2,2))

假设我们的数组有一些新的随机x,y,z索引

x,y,z = np.meshgrid(array, array, array)
重新索引阵列的最快方法是什么

这里给出了一个简单的解决方案:

for x in range(0, 3):
    for y in range(0, 3):
        for z in range(0, 3):
            new_x = x_coord[x,y,z]
            new_y = y_coord[x,y,z]
            new_z = z_coord[x,y,z]

            new_array[x,y,z] = array[new_x, new_y, new_z]
是否有我不知道的一行代码

编辑

是的,有。。。非常简单:

vol = np.arange(8).reshape(2,2, 2)
arr = np.arange(2)
x,y,z = np.meshgrid(arr, arr, arr)


print(vol)
print(vol[y, x, z]) ### ---> You have to swap the axes here tho. Does anyone know why?

[[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]]
[[[0 1]
  [2 3]]

 [[4 5]
  [6 7]]]
而且速度很慢。有没有提高性能的方法?

设置:

In [54]: arr = np.arange(9).reshape(3,3)
In [55]: x = np.random.randint(0,3,(3,3))
In [56]: y = np.random.randint(0,3,(3,3))
In [57]: x
Out[57]: 
array([[2, 0, 1],
       [0, 2, 1],
       [0, 0, 1]])
In [58]: y
Out[58]: 
array([[0, 0, 0],
       [0, 1, 1],
       [0, 1, 0]])
这些索引数组的最简单应用:

In [59]: arr[x,y]
Out[59]: 
array([[6, 0, 3],
       [0, 7, 4],
       [0, 1, 3]])
迭代等价物:

In [60]: out = np.empty_like(arr)
In [61]: for i in range(3):
    ...:     for j in range(3):
    ...:         out[i,j] = arr[x[i,j], y[i,j]]
    ...:         
In [62]: out
Out[62]: 
array([[6, 0, 3],
       [0, 7, 4],
       [0, 1, 3]])
您的代码不同,因为它在迭代时修改源数组:

In [63]: arr1 = arr.copy()
In [64]: for i in range(3):
    ...:     for j in range(3):
    ...:         arr1[i,j] = arr1[x[i,j], y[i,j]]
    ...:         
In [65]: arr1
Out[65]: 
array([[6, 6, 3],
       [6, 7, 7],
       [6, 6, 6]])
没有简单的等价物


只要索引数组一起广播,就可以使用
arr[x_coord,y_coord,z_coord]
进行索引。它们都有相同的形状,这是微不足道的

In [68]: x1 = np.random.randint(0,3,(2,4))
In [69]: x1
Out[69]: 
array([[2, 0, 2, 0],
       [0, 0, 0, 2]])
In [70]: arr[x1,x1]
Out[70]: 
array([[8, 0, 8, 0],
       [0, 0, 0, 8]])
从数组中选取随机值的一种更简单的方法是创建随机行和列选择器,并使用
ix
创建一起广播的数组:

In [71]: x1 = np.random.randint(0,3,(3))
In [72]: y1 = np.random.randint(0,3,(3))

In [75]: np.ix_(x1,y1)
Out[75]: 
(array([[2],
        [1],
        [1]]), array([[2, 2, 1]]))
In [76]: arr[np.ix_(x1,y1)]
Out[76]: 
array([[8, 8, 7],
       [5, 5, 4],
       [5, 5, 4]])

听起来好像你只是想洗牌数组的值,比如:

In [95]: arr
Out[95]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [96]: np.random.shuffle(arr.ravel())
In [97]: arr
Out[97]: 
array([[0, 1, 2],
       [7, 4, 3],
       [6, 5, 8]])

如果您的示例使用整数进行索引并起作用,它会更好。为您修复了它!现在好多了?还是要我举个恰当的例子?我觉得这个想法应该很简单?我不知道为什么在numpy中没有简单的操作来做这件事,因为我认为这只是一个简单的重新索引任务@miraduloCan你能用语言解释一下你的算法在做什么吗?
randint
将简化随机值的生成。你有没有尝试过
arr[xcord,ycord,zcord]
?我刚刚创建了一个随机数组,以便简化“问题”的输入。但最终只有一个指数对应另一个指数。因此,基本上是基于新变换索引的值排列。无论如何,如果3个坐标数组具有正确的值和形状,它们可以像我首先指出的那样使用
arr[x,y,z]