需要优雅的numpy argmin解决方案。

3 投票
2 回答
8480 浏览
提问于 2025-04-16 19:01

在Python中,如果我想找到数组中最小值的索引,我会用y = numpy.argmin(someMat)这行代码。

我能否以一种简单的方式找到这个矩阵中的最小值,并且这个最小值不在指定的范围内呢?

2 个回答

4

我猜这就是你想要实现的效果:

对于数组的最小值索引:

>>> from numpy import *
>>> a = array( [2,3,4] )
>>> argmin(a)
0
>>> print a[argmin(a)]
2

对于矩阵的最小值索引:

>>> b=array( [[6,5,4],[3,2,1]] )
>>> argmin(b)
5
>>> print b[argmin(b)]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: index out of bounds

用来索引的相同方法在数组上不适用。原因是,argmin(还有argmax)返回的是变量的索引——在矩阵的情况下,你需要把你的多维矩阵转换成一维的索引数组。

为了做到这一点,你需要调用 ravel

>>> print b
[[6 5 4]
 [3 2 1]]
>>> ravel(b)
array([6, 5, 4, 3, 2, 1])

当你把 ravel 和 argmin 结合使用时,你必须这样写:

>>> print ravel(b)[argmin(b)]
7

“我能否以一种简洁的方式找到这个矩阵的最小值,使其不在指定的范围内?”

如果你只关心满足某些条件的最小值,而不在乎它的位置,那么

>>> numpy.random.seed(1)
>>> m = numpy.random.randn(5.,5.)
>>> m
array([[ 1.62434536, -0.61175641, -0.52817175, -1.07296862,  0.86540763],
       [-2.3015387 ,  1.74481176, -0.7612069 ,  0.3190391 , -0.24937038],
       [ 1.46210794, -2.06014071, -0.3224172 , -0.38405435,  1.13376944],
       [-1.09989127, -0.17242821, -0.87785842,  0.04221375,  0.58281521],
       [-1.10061918,  1.14472371,  0.90159072,  0.50249434,  0.90085595]])
>>> m[~ ((m < 0.5) | (m > 0.8))].min()
0.50249433890186823

如果你想通过 argmin 来获取位置,那就有点复杂了,但一种方法是使用掩码数组:

>>> numpy.ma.array(m,mask=((m<0.5) | (m > 0.8))).argmin()
23
>>> m.flat[23]
0.50249433890186823

注意,这里的条件是反过来的,因为掩码对于被排除的值是 True,而不是包含的值。


更新:看起来你所说的“在指定范围内”并不是指最小值不在某些边界内,而是你想根据 x,y 坐标排除矩阵中的某些部分。这里有一种方法(和之前的矩阵一样):

>>> xx, yy = numpy.indices(m.shape)
>>> points = ((xx == 0) & (yy == 0)) | ((xx > 2) & (yy < 3))
>>> points
array([[ True, False, False, False, False],
       [False, False, False, False, False],
       [False, False, False, False, False],
       [ True,  True,  True, False, False],
       [ True,  True,  True, False, False]], dtype=bool)
>>> m[points]
array([ 1.62434536, -1.09989127, -0.17242821, -0.87785842, -1.10061918,
        1.14472371,  0.90159072])
>>> m[points].min()
-1.1006191772129212

如果你需要位置的话,这里有对应的掩码数组变体。[编辑过,使用索引而不是 mgrid;我其实是今天在看到另一个答案时才想起来的!]

如果我还是错了 :^) 而这也不是你想要的,请编辑你的问题,提供一个 3x3 的示例,说明你期望的输入和输出。

撰写回答