python numpy ndarray的缺省值

mzsu5hc0  于 2022-12-25  发布在  Python
关注(0)|答案(2)|浏览(193)

我正在使用numpy.ndarray,有趣的事情发生了。我创建了一个形状为(2,2)的数组,并将其他所有内容保留为默认值。它为我创建了一个具有以下值的数组:

array([[2.12199579e-314, 0.00000000e+000],
       [5.35567160e-321, 7.72406468e-312]])

我用相同的默认值创建了另一个数组,它也给了我相同的结果。
然后我创建了一个新的数组(使用默认值和形状(2,2)),并使用“fill”方法将其填充为零。有趣的是,现在每当我使用ndarray创建一个新数组时,它都会给我一个值为0的数组。

k97glaaz

k97glaaz1#

参见https://numpy.org/doc/stable/reference/generated/numpy.empty.html#numpy.empty:(与@Michael Butscher的评论完全一致)
np.empty([2, 2])创建一个数组,但不触及为该数组分配的内存块的内容;因此阵列看起来好像填充了一些或多或少的随机值。
np.ndarray([2, 2])执行相同的操作。
但是,其他创建方法会使用一些值填充内存:
np.zeros([2, 2])用零填充存储器,np.full([2, 2], 9)用九填充存储器,等等。
现在,如果你在创建(和处理,即自动垃圾收集)一个用1填充的数组后通过np.empty()创建一个新数组,你的新数组可能会被分配相同的内存块,因此看起来好像是用1“填充”的。

lnvxswe2

lnvxswe22#

np.empty明确表示它返回:

Array of uninitialized (arbitrary) data of the given shape, dtype, and
    order.  Object arrays will be initialized to None.

它是编译过的代码,所以我不能肯定,但我强烈怀疑它只是调用np.ndarray,带有shape和dtype。
ndarray将自己描述为一个低级函数,并列出了许多更好的替代方法。
在ipython会话中,我可以创建两个数组:

In [2]: arr = np.empty((2,2), dtype='int32'); arr
Out[2]: 
array([[  927000399,  1267404612],
       [ 1828571807, -1590157072]])

In [3]: arr1 = np.ndarray((2,2), dtype='int32'); arr1
Out[3]: 
array([[  927000399,  1267404612],
       [ 1828571807, -1590157072]])

这些值是相同的,但是当我检查它们的数据缓冲区的“位置”时,我发现它们是不同的:

In [4]: arr.__array_interface__['data'][0]
Out[4]: 2213385069328
In [5]: arr1.__array_interface__['data'][0]
Out[5]: 2213385068176

我们不能在代码中使用这个数字来改变值,但是它可以作为一个可读的指示器来指示数据存储的位置(你了解数组如何存储的基本知识吗,包括shape、dtype、stride和data-buffer)?
为什么“未初始化的值”是相同的是任何人的猜测;我猜这只是以前如何使用内存位的一个人工产物。np.empty强调我们不应该对这些值赋予重要性。
再次执行ndarray,将生成不同的值和位置:

In [9]: arr1 = np.ndarray((2,2), dtype='int32'); arr1
Out[9]: 
array([[1469865440,        515],
       [         0,          0]])
In [10]: arr1.__array_interface__['data'][0]
Out[10]: 2213403372816

明显重复使用

如果我没有将数组赋给变量,或者“hang on to it”,numpy可能会重用数据缓冲区内存:

In [17]: np.ndarray((2,2), dtype='int').__array_interface__['data'][0]
Out[17]: 2213403374512
In [18]: np.ndarray((2,2), dtype='int').__array_interface__['data'][0]
Out[18]: 2213403374512
In [19]: np.ndarray((2,2), dtype='int').__array_interface__['data'][0]
Out[19]: 2213403374512
In [20]: np.empty((2,2), dtype='int').__array_interface__['data'][0]
Out[20]: 2213403374512

同样,我们不应该把这种重用放在太重要的位置,当然也不应该指望它进行任何计算。

对象数据类型

如果我们指定object dtype,那么值被初始化为None。这个dtype包含指向内存中对象的引用/指针,“随机”指针是不安全的。

In [14]: arr1 = np.ndarray((2,2), dtype='object'); arr1
Out[14]: 
array([[None, None],
       [None, None]], dtype=object)

In [15]: arr1 = np.ndarray((2,2), dtype='U3'); arr1
Out[15]: 
array([['', ''],
       ['', '']], dtype='<U3')

相关问题