为什么链式(间隔)比较在numpy数组上不起作用?

2024-10-03 23:18:19 发布

您现在位置:Python中文网/ 问答频道 /正文

a < b < c是Python中的一个chained expression,它看起来像是在定义了适当的比较运算符的对象上工作,但它不适用于numpy数组。为什么?在

import numpy as np

class ContrarianContainer(object):
    def __init__(self, x):
        self.x = x
    def __le__(self, y):
        return not self.x <= y
    def __lt__(self, y):
        return not self.x < y
    def __ge__(self, y):
        return not self.x >= y
    def __gt__(self, y):
        return not self.x > y
    def __eq__(self, y):
        return not self.x == y
    def __ne__(self, y):
        return not self.x != y

numlist = np.array([1,2,3,4])
for n in numlist:
    print 0 < n < 3.5
for n in numlist:
    print 0 > ContrarianContainer(n) > 3.5
print 0 < numlist < 3.5

打印:

^{pr2}$

Tags: inselfnumpyforreturn定义defnp
2条回答

所以医生说:

Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.

以及

(but in both cases z is not evaluated at all when x < y is found to be false).

对于标量

In [20]: x=5
In [21]: 0<x<10
Out[21]: True
In [22]: 0<x and x<10
Out[22]: True

但是用一个数组

^{pr2}$

在需要标量布尔值的上下文中使用numpy布尔值时,会出现此值错误。在

In [26]: (0<x)
Out[26]: array([ True,  True,  True], dtype=bool)

In [30]: np.array([True, False]) or True
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [33]: if np.array([True, False]): print('yes')
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

它计算0<x,但甚至不能计算x<10,因为它不能在or/and上下文中使用得到的布尔数组。numpy定义了|和{},但没有or或{}。在

In [34]: (0<x) & x<10
Out[34]: array([ True,  True,  True], dtype=bool)

当我们使用0 < x <10时,我们隐含地期望计算标量链表达式的矢量化版本。在

In [35]: f = np.vectorize(lambda x: 0<x<10, otypes=[bool])
In [36]: f(x)
Out[36]: array([ True,  True,  True], dtype=bool)
In [37]: f([-1,5,11])
Out[37]: array([False,  True, False], dtype=bool)

请注意,尝试对列表应用链接甚至不会超过第一个<

In [39]: 0 < [-1,5,11]
TypeError: unorderable types: int() < list()

这组表达式表示&运算符优先于<运算符:

In [44]: 0 < x & x<10
ValueError ...

In [45]: (0 < x) & x<10
Out[45]: array([ True,  True,  True], dtype=bool)

In [46]: 0 < x & (x<10)
Out[46]: array([False,  True, False], dtype=bool)

In [47]: 0 < (x & x)<10
ValueError...

所以安全版本是(0 < x) & (x<10),确保所有{}在{之前求值。在

0 < numlist < 3.5

相当于:

^{pr2}$

只是numlist只计算一次。在

两个结果之间的隐式and导致了错误

相关问题 更多 >