【问题标题】:options for applying conditions to numpy arrays将条件应用于 numpy 数组的选项
【发布时间】:2013-05-01 17:28:48
【问题描述】:

我想将条件应用于 numpy 数组,我觉得那里有更好的方法。作为一个玩具示例,我想知道元素在哪里等于 2 或 3。

import numpy as np
a = np.arange(5)

一种方法是使用像这样的 numpy 函数逐个构造我的条件

result = np.logical_or(a == 2, a == 3)

我们可以看到,在更复杂的条件下,这会变得多么笨拙。另一种选择是使用列表推导

result = np.array([x for x in a if x == 2 or x==3])

这很好,因为现在我所有的条件逻辑都可以放在一个地方,但由于与列表之间的转换,感觉有点笨拙。它对于多维数组也不太适用。

有没有更好的选择我错过了?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    需要指出的是,在第一个示例中,您有一个逻辑数组,而不是数组 [2, 3](就像您在第二个示例中看到的那样)。要从第二个答案中恢复结果,您需要

    result = a[result]
    

    但是,在这种情况下,由于您使用的是布尔掩码(True/False 大约相当于 1/0),您实际上可以按位使用或执行与 @987654327 相同的操作@:

    result = a[(a==2) | (a==3)]
    

    这里要注意一点——确保使用括号。否则,这些表达式中的运算符优先级可能会有点讨厌(| 绑定比== 更紧密)。

    【讨论】:

    • (a==2)|(a==3) 正是我想要的。谢谢
    • @Hammer -- 是的。通常,我们期望数学运算比相等更紧密:if foo + 2 == 3: ...numpy 覆盖相等以返回数组的事实(以非常有用的方式)使得在某些情况下确实希望让 == 绑定更紧密,这真的会让你有点弯曲。
    【解决方案2】:

    您可以使用deletenumpy array 中删除元素

    np.delete(a,[0,1,4])
    

    或者如果你想保留补语,

    np.delete(a,np.delete(a,[2,3]))
    

    【讨论】:

      【解决方案3】:

      您可以 & 一起使用视图以获得任意复杂的结果:

      >>> A = np.random.randint(0, 100, 25).reshape(5,5)
      >>> A
      array([[98,  4, 46, 40, 24],
             [93, 75, 36, 19, 63],
             [23, 10, 62, 14, 59],
             [99, 24, 57, 78, 74],
             [ 1, 83, 52, 54, 27]])
      >>> A>10
      array([[ True, False,  True,  True,  True],
             [ True,  True,  True,  True,  True],
             [ True, False,  True,  True,  True],
             [ True,  True,  True,  True,  True],
             [False,  True,  True,  True,  True]], dtype=bool)
      >>> (A>10) & (A<20)
      array([[False, False, False, False, False],
             [False, False, False,  True, False],
             [False, False, False,  True, False],
             [False, False, False, False, False],
             [False, False, False, False, False]], dtype=bool)
      >>> (A==19) | (A==14)  # same output
      

      您也可以编写一个函数并使用 map 在每个元素上调用该函数。函数内部有任意数量的测试:

      >>> def test(ele):
      ...    return ele==2 or ele==3
      ... 
      >>> map(test,np.arange(5))
      [False, False, True, True, False]
      

      你可以使用 numpy.vectorize:

      >>> def test(x):
      ...    return x>10 and x<20
      ...
      >>> v=np.vectorize(test)
      >>> v(A)
      array([[False, False, False, False, False],
             [False, False, False,  True, False],
             [False, False, False,  True, False],
             [False, False, False, False, False],
             [False, False, False, False, False]], dtype=bool)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-16
        • 1970-01-01
        • 2019-05-04
        • 1970-01-01
        • 1970-01-01
        • 2019-07-25
        • 2014-04-20
        相关资源
        最近更新 更多