【问题标题】:How to perform element-wise Boolean operations on NumPy arrays [duplicate]如何对 NumPy 数组执行逐元素布尔运算 [重复]
【发布时间】:2012-01-27 18:09:36
【问题描述】:

例如,我想创建一个掩码来屏蔽值在 40 到 60 之间的元素:

foo = np.asanyarray(range(100))
mask = (foo < 40).__or__(foo > 60)

看起来很丑。我不会写

(foo < 40) or (foo > 60)

因为我最终得到:

  ValueError Traceback (most recent call last)
  ...
  ----> 1 (foo < 40) or (foo > 60)
  ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

有没有一种规范的方法可以用好看的代码对 NumPy 数组进行逐元素布尔运算?

【问题讨论】:

    标签: python numpy boolean-operations


    【解决方案1】:

    试试这个:

    mask = (foo < 40) | (foo > 60)
    

    注意:对象中的 __or__ 方法重载了按位或运算符 (|),而不是布尔运算符 or。

    【讨论】:

    • 它不起作用:TypeError: ufunc 'bitwise_or' not supported for the input types,并且输入无法根据强制转换规则''safe''安全地强制转换为任何支持的类型
    • 不要忘记正确地括号你的表达式
    • 嗯...为什么需要括号?
    • @flow2k 原因是按位或比比较运算符具有更高的优先级(布尔或不会发生这种情况)。欲了解更多信息,请查看documentation
    • @flow2k 我认为您正在寻找的文档是 here:|>>。
    【解决方案2】:

    如果您仅在布尔值中进行比较,如您的示例所示,您可以按照 Jcollado 的建议使用按位 OR 运算符 |。但请注意,如果您曾经使用非布尔值,例如mask = (foo &lt; 40) | override,这可能会给您带来奇怪的结果。只要override 保证为 False、True、1 或 0,就可以了。

    更通用的是使用 NumPy 的比较集运算符np.any 和np.all。这个 sn-p 返回 35 到 45 之间小于 40 或不是 3 的倍数的所有值:

    import numpy as np
    foo = np.arange(35, 46)
    mask = np.any([(foo < 40), (foo % 3)], axis=0)
    print foo[mask]
    OUTPUT: array([35, 36, 37, 38, 39, 40, 41, 43, 44])
    

    它不如| 好,但比你问题中的代码好。

    【讨论】:

    • 最好专门使用np.any 和np.all。
    • 如果您正在考虑其他解决方案,请不要。它将为您节省很多痛苦!
    • 请注意,np.any / np.all 逗号足以分隔数组条件(括号 () 内不需要括号 [] ),并且您可以有两个以上的条件(已评估只要设置了axis=0,就元素而言),只要它们是相同的类型(例如,所有连词或所有替代品,但不是连词和替代品的混合)
    【解决方案3】:

    请注意,您可以使用~ 进行元素否定。

    arr = np.array([False, True])
    ~arr
    
    OUTPUT: array([ True, False], dtype=bool)
    

    &amp; 也按元素和

    arr_1 = np.array([False, False, True, True])
    arr_2 = np.array([False, True, False, True])
    
    arr_1 & arr_2
    
    OUTPUT:   array([False, False, False,  True], dtype=bool)
    

    这些也适用于 Pandas 系列

    ser_1 = pd.Series([False, False, True, True])
    ser_2 = pd.Series([False, True, False, True])
    
    ser_1 & ser_2
    
    OUTPUT:
    0    False
    1    False
    2    False
    3     True
    dtype: bool
    

    【讨论】:

    • 根据 numpy 文档,&amp; 似乎是 bitwise and,而不是元素。
    【解决方案4】:

    您可以使用NumPy logical operations。在您的示例中:

    np.logical_or(foo < 40, foo > 60)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-30
      • 2016-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      相关资源
      最近更新 更多