【问题标题】:Python: finding index of an array under several conditionsPython:在几种条件下查找数组的索引
【发布时间】:2013-05-11 13:14:34
【问题描述】:

我有以下问题。有两个 n 维整数数组,我需要确定满足多个条件的项目的索引。

  • 索引在“array1”中应该有一个负元素。
  • 在这个带有负元素的子集中,它应该在“array2”中具有最小值。
  • 如果出现平局,请选择“array1”中具有最小值的值(否则为第一个)

所以假设我们有:

array1 = np.array([1,-1,-2])
array2 = np.array([0,1,1])

然后它应该返回索引 2(第三个数字)。我正在尝试按如下方式进行编程:

import numpy as np
n = 3
array1 = np.array([1,-1,-2])
array2 = np.array([0,1,1])
indices = [i for i in range(n) if array1[i]<0] 
indices2 = [i for i in indices if array2[i] == min(array2[indices])] 
index = [i for i in indices2 if array1[i] == min(array1[indices2])][0] #[0] breaks the tie.

这似乎可行,但是,我觉得它不是很优雅。对我来说,您似乎应该能够在一两行中完成此操作,并且定义较少的新变量。有人有改进的建议吗?提前致谢。

【问题讨论】:

  • 您的数组似乎是一维的,大小为 n,而不是 n 维
  • 我通常交替使用术语向量和数组,这可能是错误的做法:)。我的意思是 n 维向量。

标签: python conditional-statements indices


【解决方案1】:

您可以通过以下方式从 array1 中获取所有负元素的索引:

np.where(array1 < 0)

然后您可以通过以下方式访问子集:

subset = array2[array1 < 0]

要获取array1的最小(负)值的索引,可以使用array1.argmin()

value = array2[array1.argmin()]

把所有东西放在一起给你:

value = array2[array1 < 0][array1[array1 < 0].argmin()]

但如果 array1 只有正值,则必须捕获 ValueErrors。

【讨论】:

  • 是的,这与我所拥有的最接近,而且很容易理解。我只会在有负面元素时执行这部分,顺便说一句,所以不用担心。 np.where 函数非常有用......我还没有发现。非常感谢!我确实接受了其他答案,因为它更复杂。
  • 使用布尔掩码对数组进行切片比 np.where array1[array1
  • 感谢您的提示,我会努力记住的。
【解决方案2】:

我对 numpy 不太了解(虽然显然我应该研究一下),所以这里有一个简单的 python 解决方案

这个

sorted([(y, x, index) for (index, (x, y)) in enumerate(zip(array1, array2)) if x < 0])

将为您提供来自 array2、array1 的元素的三元组,按 array2 中的值排序的索引和 array1 中的值在平局的情况下,在平局的情况下的索引

第一个元素是你所寻求的。这给出了以下结果:

[(1, -2, 2), (1, -1, 1)]

因此索引为2,由[0][2]获得

【讨论】:

  • 这对我来说简直就是魔法!十分优雅。不过,我还不完全理解为什么这会起作用,因为我还不是 100% 熟悉 python。不过我会发现的:)
【解决方案3】:

索引在“array1”中应该有一个负元素

indices_1 = np.argwhere(array1 < 0)

在这个带有负元素的子集中,它应该是“array2”中的最小值。

indices_2 = array2[indices_1].argmin()

如果出现平局,则选择“array1”中具有最小值的值(否则为第一个)

array1[indices_2].argmin()

【讨论】:

  • argmin() 只为我返回一个元素...这就是我避免使用它的原因。
【解决方案4】:

我想出了这个。刚刚设计了一个测试用例,似乎可以工作。看看它是否适合您的需求。

sorted([(array2[index], element, index) for index, element in enumerate(array1) if element<0])[0][2]

或者通过使用min函数。

min([(array2[index], element, index) for index, element in enumerate(array1) if element<0])[2]

【讨论】:

    【解决方案5】:

    以下内容适用于任何维度的 numpy 数组。 它使用numpy.lexsort 对索引进行排序。

    numpy.lexsort(Y,X) 按升序对 X 中的项目进行排序,并根据 Y 中的值打破平局。它按顺序返回索引(不是 XY 的值。)这是唯一的函数我知道在 numpy 中为您“打破关系”。


    import numpy as np
    def find_index(array1, array2):
        indices = np.where(array1 < 0)
        i = np.lexsort((array1[indices],array2[indices]))[0]
        return [idx[i] for idx in indices]
    
    array1 = np.array([1,-1,-2])
    array2 = np.array([0,1,1])
    
    array3 = np.array([(1, 2),
                       (-1, -2),
                       (-2, 0)])
    array4 = np.array([(0, 2),
                       (1, 1),
                       (3, 0)])
    
    print(find_index(array1, array2))
    # [2]
    
    print(find_index(array3, array4))
    # [1, 1]
    

    【讨论】:

      猜你喜欢
      • 2018-04-20
      • 2016-08-12
      • 1970-01-01
      • 2020-12-21
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多