为什么 "None in numpy.asarray(...)" 会导致未来的警告
Why does "None in numpy.asarray(...)" cause a future warning
未来的警告会在您执行以下操作时发生:
>>> numpy.asarray([1,2,3,None]) == None
目前 return 是 False
,但我知道 return 一个包含 [False,False,False,True]
的数组会出现在 Numpy 的未来版本中。
正如所讨论的 on the numpy discussion list 解决此问题的方法是测试 a is None
。
让我感到困惑的是 in
关键字与一维数组相比列表的这种行为:
>>> None in [1,2,3,None]
True
>>> None in numpy.asarray([1,2,3,None])
__main__:1: FutureWarning: comparison to 'None' will result in an elementwise
object comparison in the future
False
>>> 1 in numpy.asarray([1,2,3,None])
True
编辑(见评论)——实际上有两个不同的问题:
- 为什么这会导致
FutureWarning
- None in numpy.asarray(...)
的未来行为与现在相比会怎样?
- 为什么
in
与 list
的行为不同;我可以测试我的数组是否包含 None
而无需将其转换为列表或使用 for
循环吗?
Numpy 版本是 1.9.1,Python3.4.1
The future warning happens when you do something like this:
numpy.asarray([1,2,3,4]) == None
Which currently returns False
, but I understand will return an array containing [False,False,False,True]
in a future version of Numpy.
正如我在评论中提到的,您的示例不正确。 numpy 的未来版本将 return [False ,False, False, False]
,即数组中每个不等于 None
的元素 False
。这与当前与其他标量值的逐元素比较的工作方式更加一致,例如:
In [1]: np.array([1, 2, 3, 4]) == 1
Out[1]: array([ True, False, False, False], dtype=bool)
In [2]: np.array(['a', 'b', 'c', 'd']) == 'b'
Out[2]: array([False, True, False, False], dtype=bool)
What confuses me is this behaviour of the in
keyword with a 1D array compared to a list
当您测试 x in y
时,您正在调用 y.__contains__(x)
。当 y
是一个列表时,__contains__
基本上按照以下方式做一些事情:
for item in y:
if (item is x) or (item == x):
return True
return False
据我所知,np.ndarray.__contains__(x)
执行的相当于:
if any(y == x):
return True
else:
return False
也就是说它首先测试整个数组的元素相等性(y == x
将是一个大小为 y
的布尔数组)。由于在您的情况下您正在测试是否 y == None
,这将出于上述原因提高 FutureWarning
。
在评论中你也想知道为什么
np.nan in np.array([1, 2, 3, np.nan])
returns False
,但是
np.nan in [1, 2, 3, np.nan]
returns True
。第一部分很容易解释为 np.nan != np.nan
(see here for the rationale behind this)。要理解为什么第二种情况 returns True
,请记住 list.__contains__()
在检查相等性 (==
) 之前首先检查身份 (is
)。由于np.nan is np.nan
,第二种情况会return True
.
未来的警告会在您执行以下操作时发生:
>>> numpy.asarray([1,2,3,None]) == None
目前 return 是 False
,但我知道 return 一个包含 [False,False,False,True]
的数组会出现在 Numpy 的未来版本中。
正如所讨论的 on the numpy discussion list 解决此问题的方法是测试 a is None
。
让我感到困惑的是 in
关键字与一维数组相比列表的这种行为:
>>> None in [1,2,3,None]
True
>>> None in numpy.asarray([1,2,3,None])
__main__:1: FutureWarning: comparison to 'None' will result in an elementwise
object comparison in the future
False
>>> 1 in numpy.asarray([1,2,3,None])
True
编辑(见评论)——实际上有两个不同的问题:
- 为什么这会导致
FutureWarning
-None in numpy.asarray(...)
的未来行为与现在相比会怎样? - 为什么
in
与list
的行为不同;我可以测试我的数组是否包含None
而无需将其转换为列表或使用for
循环吗?
Numpy 版本是 1.9.1,Python3.4.1
The future warning happens when you do something like this:
numpy.asarray([1,2,3,4]) == None
Which currently returns
False
, but I understand will return an array containing[False,False,False,True]
in a future version of Numpy.
正如我在评论中提到的,您的示例不正确。 numpy 的未来版本将 return [False ,False, False, False]
,即数组中每个不等于 None
的元素 False
。这与当前与其他标量值的逐元素比较的工作方式更加一致,例如:
In [1]: np.array([1, 2, 3, 4]) == 1
Out[1]: array([ True, False, False, False], dtype=bool)
In [2]: np.array(['a', 'b', 'c', 'd']) == 'b'
Out[2]: array([False, True, False, False], dtype=bool)
What confuses me is this behaviour of the
in
keyword with a 1D array compared to a list
当您测试 x in y
时,您正在调用 y.__contains__(x)
。当 y
是一个列表时,__contains__
基本上按照以下方式做一些事情:
for item in y:
if (item is x) or (item == x):
return True
return False
据我所知,np.ndarray.__contains__(x)
执行的相当于:
if any(y == x):
return True
else:
return False
也就是说它首先测试整个数组的元素相等性(y == x
将是一个大小为 y
的布尔数组)。由于在您的情况下您正在测试是否 y == None
,这将出于上述原因提高 FutureWarning
。
在评论中你也想知道为什么
np.nan in np.array([1, 2, 3, np.nan])
returns False
,但是
np.nan in [1, 2, 3, np.nan]
returns True
。第一部分很容易解释为 np.nan != np.nan
(see here for the rationale behind this)。要理解为什么第二种情况 returns True
,请记住 list.__contains__()
在检查相等性 (==
) 之前首先检查身份 (is
)。由于np.nan is np.nan
,第二种情况会return True
.