我和numpy一起工作。有趣的事情发生了。我创建了一个形状为(2,2)的数组,其余的都保持默认值。它用这些值为我创建了一个数组:
array([[2.12199579e-314, 0.00000000e+000],
[5.35567160e-321, 7.72406468e-312]])
我创建了另一个具有相同默认值的数组,它也给了我相同的结果。
然后我创建了一个新的数组(使用默认值和形状(2,2)),并使用'fill'方法填充零。有趣的是,现在每当我用narray创建一个新数组它都会给我一个0值的数组。那么幕后到底发生了什么呢?
参见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])
用0填充内存,np.full([2, 2], 9)
用9等填充内存
现在,如果你在创建(并处理,即自动垃圾收集)一个由e.g.填充的数组后通过np.empty()
创建一个新的数组,你的新数组可能会被分配相同的内存块,因此看起来好像"填满"的。
np.empty
明确表示返回:
Array of uninitialized (arbitrary) data of the given shape, dtype, and
order. Object arrays will be initialized to None.
这是编译的代码,所以我不能肯定地说,但我强烈怀疑它只是调用np.ndarray
,形状和dtype。
ndarray
将自己描述为一个低级函数,并列出了许多更好的替代方案。
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
我们不能在代码中使用这个数字来篡改值,但是它作为一个人类可读的数据存储位置的指示器是有用的。(您是否了解数组的基本存储方式,包括形状、dtype、strides和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
明显重用
如果我不将数组赋值给变量,或者"挂起它",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
同样,我们不应该把这种重用看得太重要,当然也不应该指望它用于任何计算。
对象dtype
如果指定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')