【问题标题】:Why does "None in numpy.asarray(...)" cause a future warning为什么“numpy.asarray(...) 中没有”会导致未来的警告
【发布时间】:2015-04-04 21:39:01
【问题描述】:

当您执行以下操作时会出现未来警告:

>>> numpy.asarray([1,2,3,None]) == None

目前返回 False,但我知道在 Numpy 的未来版本中将返回一个包含 [False,False,False,True] 的数组。

正如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

编辑(见 cmets)——实际上有两个不同的问题:

  1. 为什么这会导致 FutureWarning - None in numpy.asarray(...) 的未来行为与现在相比会怎样?
  2. 为什么inlist 的行为不同;我可以在不将其转换为列表或使用for 循环的情况下测试我的数组是否包含None

Numpy 版本是 1.9.1,Python 3.4.1

【问题讨论】:

  • 为什么你的数组会包含None?查看dtype 示例的None。那是你要的吗?您是否有可能将Nonenp.nan 混淆?
  • 我使用的数据可能包含None。我知道None 不是np.nan。我的确切情况比我的示例更复杂,但这与问题并不真正相关。不过,查看dtype 确实有效。谢谢。顺便说一句,np.nan in np.asarray([1,2,3,np.nan]) 也将返回False。所以也许我的问题应该是关于 in 和一般的 numpy 数组。
  • 尽管,如果您从其中包含 None 的矩阵中取出一个切片,dtype 仍将是 object,即使该切片中没有 None
  • @matches np.nan in np.asarray([1,2,3,np.nan]) 返回 False,因为 np.nan != np.nan(有关详细信息,请参阅 here)。在您的数据上下文中,None 的值是什么意思?如果您使用None 表示缺失数据,使用np.nan 会更有意义,或者更好的是,切换到masked arrays
  • 另外,在 numpy 的未来版本中,您的示例 np.array([1, 2, 3, 4]) == None 将返回 np.array([False ,False, False, False])。新行为将与当前与标量数值进行元素比较的方式一致,例如np.array([1, 2, 3, 4]) == 1 返回np.array([True ,False, False, False])

标签: python numpy nan


【解决方案1】:

当您执行以下操作时会出现未来警告:

numpy.asarray([1,2,3,4]) == None

目前返回 False,但我知道在 Numpy 的未来版本中将返回一个包含 [False,False,False,True] 的数组。

正如我在 cmets 中提到的,您的示例不正确。 numpy 的未来版本将返回[False ,False, False, False],即False 用于数组中不等于None 的每个元素。这与当前与其他标量值的逐元素比较的工作方式更加一致,例如:

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)

让我感到困惑的是in 关键字与一维数组相比列表的这种行为

当您测试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

在 cmets 你也想知道为什么

np.nan in np.array([1, 2, 3, np.nan])

返回False,但是

np.nan in [1, 2, 3, np.nan]

返回True。第一部分很容易解释为np.nan != np.nan (see here for the rationale behind this)。要了解为什么第二种情况返回 True,请记住 list.__contains__() 在检查相等性 (==) 之前首先检查身份 (is)。由于np.nan is np.nan,第二种情况会返回True

【讨论】:

  • 对不起!我没有注意到我的示例应该是 [1,2,3,None] == None 而不是 [1,2,3,4] == None - 我已经更正了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-03
  • 2012-02-24
  • 1970-01-01
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多