Python 2.7 通过三维阵列沿任意线切割一定宽度的长方体

Python 2.7 通过三维阵列沿任意线切割一定宽度的长方体,python-2.7,numpy,multidimensional-array,slice,Python 2.7,Numpy,Multidimensional Array,Slice,我有一个大的(600600)numpy数组,里面装满了我的数据。现在我想从这个框中提取任意线周围给定宽度的区域 对于这条线,我有单独的numpy数组中每个点的x,y和z坐标。假设线在数据框中有35个点,那么x,y和z数组的长度也都是35。我可以使用这样的索引来提取直线上的点 extraction = data[z,y,x] 现在,理想情况下,我希望通过执行以下操作来提取它周围的一个框 extraction = data[z-3:z+3,y-3:y+3,z-3:z+3] 但因为x、y和z是数组

我有一个大的(600600)numpy数组,里面装满了我的数据。现在我想从这个框中提取任意线周围给定宽度的区域

对于这条线,我有单独的numpy数组中每个点的x,y和z坐标。假设线在数据框中有35个点,那么x,y和z数组的长度也都是35。我可以使用这样的索引来提取直线上的点

extraction = data[z,y,x]
现在,理想情况下,我希望通过执行以下操作来提取它周围的一个框

extraction = data[z-3:z+3,y-3:y+3,z-3:z+3]
但因为x、y和z是数组,所以这是不可能的。我能想到的唯一方法就是对每个点进行for循环,所以

extraction = np.array([])
for i in range(len(x)):
    extraction = np.append(extraction,data[z[i]-3:z[i]+3,y[i]-3:y[i]+3,z[i]-3:z[i]+3])
然后对提取阵列进行整形。然而,这是非常缓慢的,在我想要防止的for循环中,每个片段之间都会有一些重叠

有没有一种简单的方法可以不使用for循环直接执行此操作

编辑: 让我用另一个想法来重新表述这个问题,这个想法也很慢。我有一条线穿过datacube。我有一个x、y和z坐标(坐标是datacube数组中的索引)列表,其中包含定义线的所有点。 例如,这些列表如下所示:

 x_line: [345 345 345 345 342 342 342 342 342 342 342 342 342 342 342 342]
 y_line: [540 540 540 543 543 543 543 546 546 546 549 549 549 549 552 552]
 z_line: [84 84 84 87 87 87 87 87 90 90 90 90 90 93 93 93]
正如您所看到的,这些坐标中的一些是相同的,因为这些线在不同的坐标中定义,然后根据数据框的分辨率进行组合。 现在我想屏蔽datacube中距离大于3个单元格的所有单元格。 对于沿直线的单个点(x_线[i]、y_线[i]、z_线[i]),这是相对容易的。我为datacube中的坐标创建了一个网格网格,然后创建了一个零掩码数组,并将所有满足条件的项置为1:

data = np.random.rand(600,600,600)
x_box,y_box,z_box = np.meshgrid(n.arange(600),n.arange(600),n.arange(600))
mask = np.zeros(np.shape(data))

for i in range(len(x_line)):
    distance = np.sqrt((x_box-x_line[i])**2 + (y_box-y_line[i])**2 + (z_box-z_line[i])**2)
    mask[distance <= 3] = 1.

extraction = data[mask == 1.]
data=np.rand.rand(600600)
x_盒,y_盒,z_盒=np.meshgrid(n.arange(600),n.arange(600),n.arange(600))
掩码=np.零(np.形状(数据))
对于范围内的i(len(x_线)):
距离=np.sqrt((x_盒-x_线[i])**2+(y_盒-y_线[i])**2+(z_盒-z_线[i])**2)
面具[距离这个怎么样

# .shape = (N,)
x, y, z = ...

# offsets in [-3, 3), .shape = (6, 6, 6)
xo, yo, zo = np.indices((6, 6, 6)) - 3

# box indices, .shape = (6, 6, 6, N)
xb, yb, zb = x + xo[...,np.newaxis], y + yo[...,np.newaxis], z + zo[...,np.newaxis]

# .shape = (6, 6, 6, N)
extractions = data[xb, yb, zb]
这将提取一系列6x6x6立方体,每个立方体“居中”在
x
y
z
中的坐标上

这将产生重复的坐标,并在边界附近的情况下失败

如果将
xyz
保存在一个数组中,则会减少冗余度,并且可以删除重复项:

# .shape = (N,3)
xyz = ...

# offsets in [-3, 3), .shape = (6, 6, 6, 3)
xyz_offset = np.moveaxis(np.indices((6, 6, 6)) - 3, 0, -1)

# box indices, .shape = (6, 6, 6, N, 3)
xyz_box = xyz + xyz_offset[...,np.newaxis,:]

if remove_duplicates:
    # shape (M, 3)
    xyz_box = xyz_box.reshape(-1, 3)
    xyz_box = np.unique(xyz_box, axis=0)

xb, yb, zb = xyz_box
extractions = data[xb, yb, zb]
这个怎么样

# .shape = (N,)
x, y, z = ...

# offsets in [-3, 3), .shape = (6, 6, 6)
xo, yo, zo = np.indices((6, 6, 6)) - 3

# box indices, .shape = (6, 6, 6, N)
xb, yb, zb = x + xo[...,np.newaxis], y + yo[...,np.newaxis], z + zo[...,np.newaxis]

# .shape = (6, 6, 6, N)
extractions = data[xb, yb, zb]
这将提取一系列6x6x6立方体,每个立方体“居中”在
x
y
z
中的坐标上

这将产生重复的坐标,并在边界附近的情况下失败

如果将
xyz
保存在一个数组中,则会减少冗余度,并且可以删除重复项:

# .shape = (N,3)
xyz = ...

# offsets in [-3, 3), .shape = (6, 6, 6, 3)
xyz_offset = np.moveaxis(np.indices((6, 6, 6)) - 3, 0, -1)

# box indices, .shape = (6, 6, 6, N, 3)
xyz_box = xyz + xyz_offset[...,np.newaxis,:]

if remove_duplicates:
    # shape (M, 3)
    xyz_box = xyz_box.reshape(-1, 3)
    xyz_box = np.unique(xyz_box, axis=0)

xb, yb, zb = xyz_box
extractions = data[xb, yb, zb]

…在我想阻止的for循环中,每个切片之间都会有一些重叠。
。我们讨论的是哪些重叠?例如,如果直线沿z轴方向移动,则点的间距将小于我在示例代码中使用的宽度为6的切片,因此for循环将包括沿z轴的某些条目z轴多次。解决这个问题的一种方法是先算出主轴,然后只沿着其他两个轴切片,但我必须做很多次,因此使用自动方式直接沿着直线切片会更方便。我建议添加一个最小的示例,并用explanat向我们显示预期的输出我在上面添加了一个更具体的代码示例你是想屏蔽一个6x6x6的立方体,还是一个半径为3的球体?你的两个示例选择了不同的选项
…在这个for循环中,每个切片之间都会有一些重叠,我想阻止它。
。我们讨论的是哪些重叠?例如,如果该行位于n沿着z轴,点的间距将小于我在示例代码中使用的宽度为6的切片,因此for循环将多次包含沿z轴的某些条目。解决此问题的一种方法是首先计算主轴,然后仅沿其他两个轴切片,但我必须多次这样做,因此它将更为复杂方便使用自动方式直接沿直线进行切片。我建议添加一个最小的示例,并向我们展示预期的输出,并对其进行解释。我添加了一个更具体的代码示例。您是否试图屏蔽一个6x6x6立方体或半径为3的球体?您的两个示例选择了不同的选项谢谢您的建议。我无法完全测试您的方法,因为我的numpy版本尚未将axis参数添加到np.unique。不幸的是,我无法在需要运行此代码的计算机上升级到比版本1.11.3更新的numpy。我在原始问题中添加了一些详细信息,希望能更清楚地说明我的问题meant@Mizuti:你能交易吗那么有重复项吗?我需要确定所有屏蔽单元格中的平均值等属性,因此有重复项是一个真正的问题。请接受您的建议。我无法完全测试您的方法,因为我的numpy版本尚未将axis参数添加到np.unique。不幸的是,我无法升级到上比版本1.11.3更新的numpy我需要在一台机器上运行这段代码。我在我的原始问题中添加了更多的信息,希望能让我的问题更清楚一些meant@Mizuti:那么你能处理重复的问题吗?我需要确定所有屏蔽单元格中的平均值之类的属性,所以重复是一个真正的问题