【发布时间】:2019-07-30 00:39:01
【问题描述】:
我试图理解由numpy“2D”数组引起的差异,即numpy.zeros((3, )), numpy.zeros((3, 1)), numpy.zeros((1, 3) )。
我使用id 查看每个元素的内存分配。但是我在 iPython 控制台中发现了一些奇怪的输出。
a = np.zeros((1, 3))
In [174]: id(a[0, 0])
Out[174]: 4491074656
In [175]: id(a[0, 1])
Out[175]: 4491074680
In [176]: id(a[0, 2])
Out[176]: 4491074704
In [177]: id(a[0, 0])
Out[177]: 4491074728
In [178]: id(a[0, 1])
Out[178]: 4491074800
In [179]: id(a)
Out[179]: 4492226688
In [180]: id(a[0, 1])
Out[180]: 4491074752
元素的记忆是
- 不连续
- 更改而不重新分配
此外,形状(1, 3)的数组中的元素一开始似乎是连续记忆的,但对于其他形状甚至不是这样,比如
In [186]: a = np.zeros((3, ))
In [187]: id(a)
Out[187]: 4490927280
In [188]: id(a[0])
Out[188]: 4491075040
In [189]: id(a[1])
Out[189]: 4491074968
In [191]: a = np.random.rand(4, 1)
In [192]: id(a)
Out[192]: 4491777648
In [193]: id(a[0])
Out[193]: 4491413504
In [194]: id(a[1])
Out[194]: 4479900048
In [195]: id(a[2])
Out[195]: 4491648416
我其实不太确定id 是否适合在 Python 中检查内存。据我所知,我想在 Python 中获取变量的物理地址并不容易。
就像 C 或 Java 一样,我希望这种“二维”数组中的元素在内存中应该是连续的,但这似乎不是真的。而且id的结果一直在变化,这让我很困惑。
我对此很感兴趣,因为我有点使用 mpi4py,我想弄清楚 CPU 之间如何发送/接收变量。
【问题讨论】:
-
根据this question 和this question,numpy 不存储数组值(?)所以当你使用
id()时,它会动态创建数组,这就是为什么“元素在没有重新分配的情况下发生变化”(?) -
id对此一无所知。这 3 个数组使用相同的底层数据缓冲区结构。基本的 numpy 文档描述了ndarray结构, -
mpi4py谈到使用 Python 缓冲区协议(以及pickle用于其他类型的对象)。numpy使用它。 jakevdp.github.io/blog/2014/05/05/… 是一个示例介绍。可能有新的、更完整的描述。 -
a.__array_interface__['data'][0]是数组a的数据缓冲区开始的整数表示。a的视图将具有附近的值。例如a[1:2],不是a[1]。
标签: python numpy memory mpi4py