这是我的代码
my_array_1 = np.arange(25).reshape(5, 5)
print(my_array_1)
my_array_red = my_array_1[:, 1::2]
print(my_array_red)
my_array_blue = my_array_1[1::2, 0:3:2]
print(my_array_blue)
my_array_yellow = my_array_1[-1, :]
print(my_array_yellow)
print(id(my_array_1))
print(id(my_array_red))
print(id(my_array_yellow))
print(id(my_array_blue))
print(my_array_1.data)
print(my_array_red.data)
print(my_array_blue.data)
print(my_array_yellow.data)
以下是输出:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
[[ 1 3]
[ 6 8]
[11 13]
[16 18]
[21 23]]
[[ 5 7]
[15 17]]
[20 21 22 23 24]
2606769150592
2606769282544
2607017647120
2606769282624
<memory at 0x0000025EFE56CA68>
<memory at 0x0000025EFE56CA68>
<memory at 0x0000025EFE56CA68>
<memory at 0x0000025EFE5A8F48>
问题: 只需检查我的输出的最后4行。为什么my_array_1.data.data,my_array_red.data和my_array_blue.data具有相同的值,但是与my_array_yellow.data具有不同的值呢?
答案 0 :(得分:2)
我发现data
的{{1}}值更有意义:
__array_interface__
In [2]: my_array_1.__array_interface__['data']
Out[2]: (33691856, False)
In [3]: my_array_red.__array_interface__['data']
Out[3]: (33691864, False)
In [4]: my_array_blue.__array_interface__['data']
Out[4]: (33691896, False)
In [5]: my_array_yellow.__array_interface__['data']
Out[5]: (33692016, False)
是数据缓冲区的开始。
Out[2]
大8字节-从一开始就是一个元素。
red
在下一行中是40个字节
blue
In [8]: my_array_1.strides
Out[8]: (40, 8)
的长度为160个字节-这是最后一行的开始(末尾40个)
yellow
In [9]: 2016-1856
Out[9]: 160
In [10]: my_array_1.nbytes
Out[10]: 200
的地址各不相同,但位于同一球场。但是它们很难解释。
data
In [11]: my_array_1.data
Out[11]: <memory at 0x7fa975369a68>
In [12]: my_array_red.data
Out[12]: <memory at 0x7fa975369b40>
In [13]: my_array_blue.data
Out[13]: <memory at 0x7fa975369c18>
In [14]: my_array_yellow.data
Out[14]: <memory at 0x7fa9710f11c8>
属性可以在data
构造函数中使用:
ndarray
中的两个元素:
yellow
相同的2个元素,但具有原始地址和偏移量(如上所述):
In [17]: np.ndarray(2,dtype=my_array_1.dtype,buffer=my_array_yellow.data)
Out[17]: array([20, 21])
实际上,In [18]: np.ndarray(2,dtype=my_array_1.dtype,buffer=my_array_1.data, offset=160)
Out[18]: array([20, 21])
显示不会告诉我们有关数据缓冲区的位置的任何信息。引用缓冲区的是data
对象的地址,而不是缓冲区本身的地址。再次调用memoryview
,并获得一个不同的memoryview对象:
data
如果我打印这些memoryview对象,则会得到与您相同的模式:
In [19]: my_array_1.data
Out[19]: <memory at 0x7fa975369cf0>
对于23和24,它只是重复使用一个内存插槽,因为使用print并没有持久性。我不确定为什么In [22]: print(my_array_1.data)
<memory at 0x7fa970e37120>
In [23]: print(my_array_red.data)
<memory at 0x7fa970e37120>
In [24]: print(my_array_blue.data)
<memory at 0x7fa970e37120>
In [25]: print(my_array_yellow.data)
<memory at 0x7fa9710f17c8>
不重用它,除非对象可能完全不同,以致于无法容纳在同一空间中。在yellow
等情况下,Out[11]
缓冲会挂在那些对象上,因此不会重用。
这只是强化了这样的观念:这些ipython
的印刷显示没有什么意义。它与数据缓冲区位置无关。它更像memoryview objects
,只是内存中的任意位置。