为什么numpy.ndarray允许使用“无”数组?

时间:2019-01-14 17:13:11

标签: python arrays numpy nonetype numpy-ndarray

我想知道numpy.ndarray的以下功能的原理是什么?

>>> a = None
>>> a = np.asarray(a)
array(None, dtype=object)

>>> type(a)
<class 'numpy.ndarray'>

>>> a == None
True

>>> a is None
False

因此,在这种情况下,Python似乎实际上创建了一个None数组(而不是Nones数组),该数组似乎对变量a进行了类型化。但是文档指出位置参数必须是“ array_like”:

  

a:array_like

     
    

可以以任何形式转换为数组的输入数据。这包括列表,元组列表,元组,元组元组,列表元组和ndarray。

  

为什么None被接受为“类似数组的”,因为它不是上面列出的任何一个?

类推,list(None)将返回错误,因为根据文档,None不是“可迭代的”。

此外,某些函数似乎实际上返回了看似不正确的值。例如,np.ndarray.argmax()np.ndarray.argmin()对于“无数组”实际上返回0,但是对于空数组会导致错误,直观上看起来像是预期的行为。

>>> a
array(None, dtype=object)
>>> b
array([], dtype=object)
>>> a.argmax()
0
>>> b.argmax()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: attempt to get argmax of an empty sequence

与空数组(array(None, dtype=object))相比,拥有“无数组”(array([], dtype=object))实际上有什么优势吗?

这是预期的功能,还是Nones是实际对象的偶然结果?有人可以解释一下引擎盖下的情况以及原因吗?

非常感谢!

2 个答案:

答案 0 :(得分:1)

使用np.asarray(None)得到的是一个形状为()的数组,它是一个scalar,形状为dtype object。如果执行np.asarray(2)np.asarray('abc'),也会得到类似的结果。标量不能被迭代,但可以与非NumPy值进行比较。同时,您将获得NumPy操作,因此您可以执行以下操作:

list(np.asarray(None).reshape((1,)))

它有效。

关于argminargmax之类的功能。请注意,标量不为空。形状为()的数组只有一个元素,但维数为零,而形状为(0,)的数组只有一个维,没有元素。这可能是违反直觉的,但是这很有意义并且也使事情正常进行。如文档所述,argminargmax在没有给出axis值的情况下,在平坦化的数组上工作。标量的扁平数组(例如np.asarray(None).ravel())是形状为(1,)的数组,并且由于您要查询的是最小值或最大值的索引,并且它只有一个值,因此答案是在两种情况下均为0。有趣的是,如果您尝试np.argmin(np.asarray([None, None]))会失败,因为现在有两个元素,您需要比较它们以知道哪个是最小的元素,但是您不能比较None的值。

答案 1 :(得分:1)

  

我想知道numpy.ndarray的以下功能的原理是什么

NumPy允许使用0维数组,并且允许使用object dtype数组。这些事实加在一起,意味着任何对象都可以解释为object dtype的0维数组,这就是numpy.array解释无法找到其他解释方式的任何参数的方式。这就是这里发生的事情。

您拥有的是一个0维1元素数组,其1个元素为None。

In [12]: x = numpy.array(None)
In [13]: x.shape
Out[13]: ()
In [14]: x.size
Out[14]: 1
In [15]: print(x.item())
None
  

因此在这种情况下,Python似乎实际上创建了一个None数组(不是Nones数组)

否,它是一个无数组。它是一个全为无的数组。您可以通过不提供任何索引的元组或调用item()方法或以其他方式访问None。

In [15]: print(x.item())
None
In [16]: print(x[()])
None
  

那为什么为什么None不能被视为“类似数组的”呢?

该列表并非详尽无遗。

  

此外,某些函数似乎实际上返回了看似不正确的值。例如,np.ndarray.argmax()或np.ndarray.argmin()对于“无数组”实际上返回0,但是对于空数组会导致错误,直观上看起来像是预期的行为。

如果不提供axis自变量,则argmaxargmin默认使用扁平化的输入形式。 0是0维数组的展平形式的唯一元素的索引。

In [23]: y = x.ravel()
In [24]: y
Out[24]: array([None], dtype=object)
In [25]: y.argmin()
Out[25]: 0
In [26]: y.argmax()
Out[26]: 0
In [27]: print(y[0])
None