如何将 3D 位置数组拆分为子体积

How to split a 3D array of positions into subvolumes

不确定之前是否有人问过这个问题——我查看了类似的例子,它们并不是我需要做的。

我在立方体中有一个位置数组 (shape = (8855470, 3)),物理坐标在 0 到 787.5 之间。这些位置代表一些 space 中的质点。下面是这个数组的前三个条目:

array([[224.90635586, 720.494766  ,  19.40263367],
   [491.25279546,  41.26026654,   7.35436416],
   [407.70436788, 340.32618713, 328.88192913]])

我想把这个巨大的立方体分成许多小的立方体。例如,如果我想将它的每一侧分成 10 个立方体,总共 1,000 个子立方体,那么每个子立方体将只包含在该子立方体中有位置的点。我一直在试验 np.meshgrid 来创建必要的 3D 网格,以便有条件地将位置数组的适当条目分配给子立方体:

split = np.arange(0.,(787.5+787.5/10.),step=787.5/10.)
xg,yg,zg = np.meshgrid(split,split,split,indexing='ij')

但我不确定这是否是解决此问题的方法。 如果这个问题太模糊或者您是否需要任何其他信息,请告诉我。

为了解决问题,我将使用玩具数据。我想你离网格很近。这是一个建议

  1. 创建网格,但不包括 757.5 之前的点,其值与您在排列中所做的相同。
  2. 重塑然后拥有 1d_array。 for in arrays zip 以获取具有立方体形状的蒙版。
  3. 创建一个列表来保存所有子立方体点。
    import numpy as np
    data = np.random.randint(0,787,( 10000,3))
    
    start = 0
    end = 787.5
    step = (end-start)/10
    split = np.arange(start,end,step)
    
    xg,yg,zg = np.meshgrid(split,split,split,indexing='ij')
    
    xg = xg.reshape(-1)
    yg = yg.reshape(-1)
    zg = zg.reshape(-1)

    subcube_data = []
    for x,y,z in zip(xg,yg,zg):
        mask_x = (x<= data[:,0] ) * ( data[:,0] < x+step) #data_x between start and end for this subcube
        mask_y = (y<= data[:,1] ) * ( data[:,1] < y+step) #data_y between start and end for this subcube
        mask_z = (z<= data[:,2] ) * ( data[:,2] < z+step) #data_z between start and end for this subcube
        mask = mask_x * mask_y * mask_z
        subcube_data.append(data[mask])

现在您将拥有一个包含 1000 个元素的列表,其中每个元素都是一个包含 Nx3 点列表的 sub_cube。如果你想恢复对应于每个 sub_cube[i] 的 3d 索引,你可以做 [xg[i],yg[i],zg[i]].

最后,您可以绘图以查看一些 sub_cube 和其余数据

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

#plot data as 3d scatter border black
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

#plot subcubes 0 1 2 3 4 in colors
for i in range(5):
    ax.scatter(subcube_data[i][:,0], 
               subcube_data[i][:,1], 
               subcube_data[i][:,2], marker='o', s=2)
for i in range(5,len(subcube_data)):
    ax.scatter(subcube_data[i][:,0], 
               subcube_data[i][:,1],
                subcube_data[i][:,2],marker='o', s=1, color='black')