【发布时间】:2022-01-18 12:02:54
【问题描述】:
让我们有一个形状等于 (36, 2, 400, 400) 的 numpy 数组 (float)。让我们说 400 x 400 代表一个图像。然后对于每个像素,我想找到两个值(第二维),它们是在第二维上取范数时,相对于第一维来说是最低的。所以我最终得到了一个形状数组 (2, 400, 400)。
使用np.argmin(np.linalg.norm(array, axis=1), axis=0),我可以得到每个 2 x 400 x 400 像素的索引,这几乎是我想要的。但是现在我想使用这个数字在第一维中对原始数组进行切片,所以我留下了一个形状为 (2, 400, 400) 的数组。
我可以做的是遍历所有索引并逐像素构造结果,但我相信有一种更智能的方法。谁能用更聪明的方法帮助我?
根据要求提供的最小可重复示例,其中距离是数组:
shape = (400, 400)
centers = np.random.randint(400, size=(36, 2))
distances = np.array([np.indices(shape) - np.array(center)[:, None, None] for center in centers])
nearest_center_index = np.argmin(np.linalg.norm(distances, axis=1), axis=0)
print(distances.shape)
print(nearest_center_index.shape)
plt.imshow(nearest_center_index)
出来:
(36, 2, 400, 400)
(400, 400)
在 cmets 的帮助下,我能够得出一个有点难看的答案,这有助于我进一步理解问题。让我详细说明。可以做的是展平图像和 argmin 结果,然后在图像上使用带有 argmin 和索引的高级索引来生成结果。
flatten_indices = nearest_center_index.reshape(400**2)
image_indices = range(400**2)
results = distances.reshape(36, 2, 400**2)[flatten_indices, :, image_indices].reshape(400, 400, 2).swapaxes(0, 2)
但是,我认为很多情况下,您的索引都被塑造为维度的子集,并且具有包含另一个维度索引的值。我希望有一个通用的方法来分割它。
因此,让我们有一个 n 维数组,形状 = (x1, x2, ..., xn),假设我们有一个数组表示一个维度的索引,例如 xi,它的形状是原始数组形状的子集,不包含 xi。然后我希望有一种方法可以对这个数组进行切片。
【问题讨论】:
-
@jjramsey - 我怀疑任何编写两行 Voronoi 地图算法的人都不熟悉基本索引。
-
@MichaelSzczesny 没错,但尽管网址中有名称,但内容实际上也涵盖了各种高级索引。
-
np.take_along_axis(distances, nearest_center_index[None,None,:,:], 0).swapaxes(3,2)这保持了 arr 的维度,就像切片通常所做的那样。而且速度有点快。 -
@MichaelSzczesny 我想这就是我想要的。至少它涵盖了我可以想象的一般问题,至少对于我能想到的所有用例,谢谢!
标签: python numpy numpy-ndarray numpy-slicing