【问题标题】:Script in function to write find second smallest value if smallest value fulfills a particular condition如果最小值满足特定条件,则在函数中编写查找第二最小值的脚本
【发布时间】:2020-12-05 18:22:32
【问题描述】:

对于我拥有的一组矩阵,称为 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]

【问题讨论】:

  • 首先使用 s = np.sort(original.ravel()) 对数组进行排序。然后找到第 k 个最小值。使用 np.where(original==required_num) 找到它的索引
  • @GirishDattatrayHegde。或者使用 argsort 并只跟踪索引。更好的是,使用 argpartition
  • @Mad Physicist 是的,这更好

标签: python numpy loops sorting iteration


【解决方案1】:

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

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)

注意nanargmina version of argmin 忽略NaNs。

【讨论】:

    【解决方案2】:

    您可以使用np.argpartition 一次找到前两个最小元素的索引。对数组的第二个元素进行分区保证了第一个元素会更小,所以你得到了两者。

    indices2 = np.unravel_index(
            np.argpartition(np.abs(distance_matrix), 1, None),
            distance_matrix.shape)
    

    您必须传递 axisNone 来分解索引而不是对列进行分区。否则你将无法直接在结果上调用np.unravel_index

    如果你想要单独的每个索引:

    i = np.argpartition(np.abs(distance_matrix), 1, None)
    indices = np.unravel_index(i[0], distance_matrix.shape)
    indices2 = np.unravel_index(i[1], distance_matrix.shape)
    

    如果你想得到更多的最小值,你必须sort数组的左边。

    k = 5
    i = np.argpartition(np.abs(distance_matrix), k, None)[:k]
    i.sort()
    indices = np.unravel_index(i, distance_matrix.shape)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-21
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-15
      • 2015-04-06
      相关资源
      最近更新 更多