首页 > 解决方案 > Numpy,Python3.6 - 无法理解为什么地址不同?

问题描述

这是我的代码

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 具有不同的值?

标签: python-3.xnumpyscipy

解决方案


我发现的data价值__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]是数据缓冲区的开始。

red大 8 个字节 - 从一开始就是一个元素。

blue是 40 个字节 - 下一行

In [8]: my_array_1.strides
Out[8]: (40, 8)

yellow是 160 个字节 - 这是最后一行的开始(距离末尾 40 个)

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

In [17]: np.ndarray(2,dtype=my_array_1.dtype,buffer=my_array_yellow.data)
Out[17]: array([20, 21])

相同的 2 个元素,但具有原始地址和偏移量(如上所述):

In [18]: np.ndarray(2,dtype=my_array_1.dtype,buffer=my_array_1.data, offset=160)
Out[18]: array([20, 21])

实际上,data显示并没有告诉我们数据缓冲区的位置。它是memoryview引用缓冲区的对象的地址,而不是缓冲区本身的地址。再次调用data,得到不同的 memoryview 对象:

In [19]: my_array_1.data
Out[19]: <memory at 0x7fa975369cf0>

如果我打印这些 memoryview 对象,我会得到与您相同的模式:

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>

对于 23 和 24,它只是重复使用内存插槽,因为使用 print 没有持久性。我不确定为什么yellow不重复使用它,除非对象可能有足够的不同以至于它不适合同一个空间。在Out[11]等情况下,ipython缓冲挂在这些对象上,因此没有重用。

它只是强化了这样一种想法,即这些memoryview objects. 它与数据缓冲区的位置无关。它更像是id,只是内存中的任意位置。


推荐阅读