Python 为什么numpy.ndarray允许一个;无”;阵列?

Python 为什么numpy.ndarray允许一个;无”;阵列?,python,arrays,numpy,nonetype,numpy-ndarray,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 与空数组(array([],dtype=object)

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

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

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

>>> a == None
True

>>> a is None
False
与空数组(
array([],dtype=object)
)相比,使用“None数组”(
array(None,dtype=object)
)实际上有什么好处吗

这是预期的功能,还是
Nones
作为实际对象的意外后果?有人能解释一下引擎盖下面发生了什么,为什么


非常感谢

np.asarray(None)是一个具有形状
()
的数组,它是一个,具有数据类型
对象的数组。如果你做
np.asarray(2)
np.asarray('abc')
,你会得到类似的结果。标量不能迭代,但可以与非NumPy值进行比较。同时,您可以使用它们执行NumPy操作,因此您可以执行以下操作:

list(np.asarray(None).reshape((1,)))
它是有效的

关于函数,如
argmin
argmax
。请注意,标量不是空的。形状为
()
的数组有一个元素,但维度为零,而形状为
(0,)
的数组只有一个维度,没有元素。这可能是违反直觉的,但它是有意义的,也能让事情顺利进行。如文件所述,
argmin
argmax
,当未给出
值时,在展平阵列上工作。标量的展平数组(例如,
np.asarray(None).ravel()
)是一个形状为
(1,)
的数组,由于您要求的是最小值或最大值的索引,而它只有一个值,因此在这两种情况下,答案都是
0
。有趣的是,如果您尝试
np.argmin(np.asarray([None,None]))
它会失败,因为现在您有两个元素,您需要比较它们以知道哪一个是最小的,但您无法比较
None

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

NumPy允许0维数组,它允许
object
dtype的数组。总之,这些事实意味着任何对象都可以被解释为一个0维数组,如
object
dtype,这就是
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
既然不是上面列出的任何一个,为什么没有一个被认为是“类似数组”的呢

该清单并非详尽无遗

此外,有些函数似乎实际上返回了看似不正确的值。例如,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
如果未提供
axis
参数,
argmax
argmin
默认使用扁平形式的输入
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

np.array(3)
也可以工作-也就是说,
np.array
也接受标量。在这种情况下,请注意
形状
数据类型
。至于哪些函数起作用,请注意3个可能的问题:
()
形状、
对象
数据类型和
值。这很有意义,谢谢您的回答!但是,就
argmin
argmax
函数而言:如果我最终指定了axis参数(因此没有使用单个元素对展平数组执行操作),它仍然返回索引0,这似乎违反直觉,主要是因为指定axis表示维度(对吗?),而
数组(None,dtype=object)
数组(3,dtype=int)
如您所述具有形状
()
,表示没有维度。@jolaem您是对的,将
argmin
/
argmax
轴=0
一起使用仍然可以使用标量,我认为这是一个错误,因为这个论点确实没有这样的轴心。使用任何其他axis值都会失败,因此我假设代码在某个点上处理类似的标量和1D数组。我想你也可以说这些函数根本不应该工作,因为标量根本不是数组。。。只有它们是
numpy.ndarray
对象,所以它们的行为确实比标量更像数组,我猜。谢谢你的回答!大部分是有意义的,但在
argmax
上有一个后续问题。如果我指定了
axis
参数,因此无法处理扁平数组,我仍然从
np.array(None).argmax(axis=0)
中获取索引0,这似乎违反直觉,因为
np.array(None)
具有
()
的形状,因此没有维度,而
axis
参数表示维度。这是为什么?@jolaem:可能是历史错误和向后兼容性。是的,看起来是这样,非常感谢你的解释!