如何使用 argmin 的输出作为 Numpy 的索引
How to use the output of argmin as index with Numpy
我想在 rank-3 numpy 数组中找到沿给定轴的最小值的位置。我已经通过 np.argmin
获得了这些位置,但是我不确定如何将其“应用”到原始矩阵以获得实际的最小值。
例如:
import numpy as np
a = np.random.randn(10, 5, 2)
min_loc = a.argmin(axis = 0) # this gives an array of shape (5, 2)
现在,问题是如何使用 min_loc
获得实际的最小值?我试过 a[min_loc]
,它给了我一个形状 (5, 2, 5, 2)
。这个形状的逻辑是什么?我如何使用这个辅助矩阵来获得形状 (5, 2)
的合理解
请注意,a.min(axis = 0)
不是我正在寻找的解决方案。我需要通过 argmin
.
的解决方案
a[min_loc]
在第一个维度上执行 integer array indexing,即它将为 min_loc
中的每个索引选择 (5, 2)
形状的数组。由于 min_loc
本身是 (5, 2)
形状的,并且对于 min_loc
中的每个整数,它会选择另一个 (5, 2)
形状的数组。你最终得到一个 (5, 2, 5, 2)
数组。同样的原因 a[np.array([0, 3])]
具有 (2, 5, 2)
的形状,a[np.array([[0], [3]])]
具有 (2, 1, 5, 2)
的形状,因为您只提供第一维的索引。
对于您的用例,您不想为 min_loc
中的每个索引选择一个子数组,而是需要一个元素。例如,如果您有 min_loc = [[5, ...], ...]
,第一个元素的完整索引应该是 5, 0, 0
而不是 5, :, :
。这正是 advanced indexing 所做的。基本上通过提供一个整数数组作为每个维度的索引,您可以提取与特定位置对应的元素。您可以使用 np.indices
:
从 (5, 2)
形状构建第 2 和第 3 维的索引
j, k = np.indices(min_loc.shape)
a[min_loc, j, k]
# [[-1.82762089 -0.80927253]
# [-1.06147046 -1.70961507]
# [-0.59913623 -1.10963768]
# [-2.57382762 -0.77081778]
# [-1.6918745 -1.99800825]]
其中 j, k
是第二维和第三维的坐标:
j
#[[0 0]
# [1 1]
# [2 2]
# [3 3]
# [4 4]]
k
#[[0 1]
# [0 1]
# [0 1]
# [0 1]
# [0 1]]
或如@hpaulj 所评论,使用np.take_along_axis
方法:
np.take_along_axis(a, min_loc[None], axis=0)
# [[[-0.93515242 -2.29665325]
# [-1.30864779 -1.483428 ]
# [-1.24262879 -0.71030707]
# [-1.40322789 -1.35580273]
# [-2.10997209 -2.81922197]]]
我想在 rank-3 numpy 数组中找到沿给定轴的最小值的位置。我已经通过 np.argmin
获得了这些位置,但是我不确定如何将其“应用”到原始矩阵以获得实际的最小值。
例如:
import numpy as np
a = np.random.randn(10, 5, 2)
min_loc = a.argmin(axis = 0) # this gives an array of shape (5, 2)
现在,问题是如何使用 min_loc
获得实际的最小值?我试过 a[min_loc]
,它给了我一个形状 (5, 2, 5, 2)
。这个形状的逻辑是什么?我如何使用这个辅助矩阵来获得形状 (5, 2)
请注意,a.min(axis = 0)
不是我正在寻找的解决方案。我需要通过 argmin
.
a[min_loc]
在第一个维度上执行 integer array indexing,即它将为 min_loc
中的每个索引选择 (5, 2)
形状的数组。由于 min_loc
本身是 (5, 2)
形状的,并且对于 min_loc
中的每个整数,它会选择另一个 (5, 2)
形状的数组。你最终得到一个 (5, 2, 5, 2)
数组。同样的原因 a[np.array([0, 3])]
具有 (2, 5, 2)
的形状,a[np.array([[0], [3]])]
具有 (2, 1, 5, 2)
的形状,因为您只提供第一维的索引。
对于您的用例,您不想为 min_loc
中的每个索引选择一个子数组,而是需要一个元素。例如,如果您有 min_loc = [[5, ...], ...]
,第一个元素的完整索引应该是 5, 0, 0
而不是 5, :, :
。这正是 advanced indexing 所做的。基本上通过提供一个整数数组作为每个维度的索引,您可以提取与特定位置对应的元素。您可以使用 np.indices
:
(5, 2)
形状构建第 2 和第 3 维的索引
j, k = np.indices(min_loc.shape)
a[min_loc, j, k]
# [[-1.82762089 -0.80927253]
# [-1.06147046 -1.70961507]
# [-0.59913623 -1.10963768]
# [-2.57382762 -0.77081778]
# [-1.6918745 -1.99800825]]
其中 j, k
是第二维和第三维的坐标:
j
#[[0 0]
# [1 1]
# [2 2]
# [3 3]
# [4 4]]
k
#[[0 1]
# [0 1]
# [0 1]
# [0 1]
# [0 1]]
或如@hpaulj 所评论,使用np.take_along_axis
方法:
np.take_along_axis(a, min_loc[None], axis=0)
# [[[-0.93515242 -2.29665325]
# [-1.30864779 -1.483428 ]
# [-1.24262879 -0.71030707]
# [-1.40322789 -1.35580273]
# [-2.10997209 -2.81922197]]]