【问题标题】:How to split a 3D array of positions into subvolumes如何将 3D 位置数组拆分为子卷
【发布时间】:2021-11-27 19:40:47
【问题描述】:

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

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

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')

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

【问题讨论】:

    标签: python numpy matrix simulation volume


    【解决方案1】:

    为了解决问题,我将使用玩具数据。我认为您在网格附近。这是一个建议

    1. 创建网格,但不包括直到 757.5 的点,其值与您在 arange 中所做的一样。
    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 个元素的列表,其中每个元素都是一个 sub_cube,其中包含一个 Nx3 点列表。如果你想恢复每个 sub_cube[i] 对应的 3d 索引,你可以做 [xg[i],yg[i],zg[i]]

    最后你可以绘制查看一些 sub_cubes 和其余数据

    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')
    

    【讨论】:

    • 太棒了,谢谢!!我不知道你可以通过这样的拉链循环,这正是我希望做的。
    • 是的,考虑到,避免 for i in range.. 是一个好习惯,而是使用 zipenumerate,第一个允许您迭代多个变量(我不知道您可以使用多少变量是否有一个好的做法..)。第二个允许你迭代一个变量并获取和索引关联:for idx,val in enumerate(someVar):..你也可以结合这两个for idx, (val1,val2 ) in enumerate(zip(var1,var2)):不要忘记( ),因为在这种情况下,枚举中的第二个值是一个元组
    猜你喜欢
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 2020-05-13
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    相关资源
    最近更新 更多