首页 > 解决方案 > 如果最小值满足特定条件,则在函数中编写查找第二最小值的脚本

问题描述

对于我拥有的一组矩阵,称为 distance_matrix (它们存在于一个函数中,然后在给定范围内生成所有这些矩阵)。我需要在这个矩阵中找到最小值,显然是由一个索引对表示的,为此我有这个代码:

min_indices = np.unravel_index(np.argmin(np.abs(distance_matrix)),np.shape(distance_matrix))

这工作得很好。但是现在我需要写一些东西,如果上面代码返回的索引是(0,0),则找到第二低的值。我想我不能使用上面的代码,因为你不能修改它来找到下一个值(据我所知)。我已经尝试过使用 if 循环,但那不是很有效:

sdiff = np.diff(np.sign(np.diff(distance_matrix)))
rising_1 = (sdiff == 2) 
rising_2 = (sdiff[:-1] == 1) & (sdiff[1:] == 1) 
rising_all = rising_1 
rising_all[1:] = rising_all[1:] | rising_2 
min_ind = np.where(rising_all)[0] + 1 
minima = list(zip(min_ind, distance_matrix[min_ind]))
for ind_pair in range(0,len(minima)):
    if ind_pair ==(0,0):
        minima=sorted(minima, key=lambda pair: pair[1])[1]
    else:
        minima=sorted(minima, key=lambda pair: pair[1])[0]

标签: pythonnumpyloopssortingiteration

解决方案


假设距离矩阵是二维的,然后使用以下测试数据:

distance_matrix = np.array([[0. , 1. , 2. ],
                            [1. , 0.5, 1.5],
                            [2. , 1.5, 2. ]])

现在,

np.unravel_index(
  np.argmin(np.abs(distance_matrix)),
  np.shape(distance_matrix)
)

为您返回(0, 0),这当然是您不想要的。但是,您是否有理由不能通过使用以下内容来实现这一目标:

mask = np.ones(np.shape(distance_matrix))
mask[0, 0] = np.nan  # you can put this in a loop if there is
                     # more than one coordinate set you don't want

distance_matrix * mask
# array([[nan, 1. , 2. ],
#        [1. , 0.5, 1.5],
#        [2. , 1.5, 2. ]])

np.unravel_index(
  np.nanargmin(np.abs(distance_matrix * mask)),
  np.shape(distance_matrix)
)
# (1, 1)

请注意,这nanargmin一个 argmin忽略NaNs 的版本。


推荐阅读