python - Numpy:每个操作的内存分配?

标签 python numpy

numpy 是否为您对矩阵执行的每个操作分配新矩阵?

例如:

A = np.random.rand(10, 20)
A = 2 * A  # Operation 1: Is a copy of A made, and a reference assigned to A?
B = 2 * A  # Operation 2: Does B get a completely different copy of A?
C = A      # Operation 3: Does C get a reference to A?

和切片操作:

A[0, :] = 3

链式操作怎么样?

D = A * B * C  # Elementwise multiplication, if A * B allocates memory, does 
               # (A * B) * C allocate another patch of memory?

Numpy 是一个很棒的库,但我只想知道幕后发生了什么。我的直觉告诉我切片操作会修改内存 View ,但我不知道赋值。

最佳答案

请记住,numpy 数组是一个 Python 对象。 Python 不断地创建和删除对象。该数组具有 .FLAGS.__array_interface__ 字典中显示的属性,例如 shapedtype。占用(可能)大量内存的属性是数据缓冲区。它可能只有几个字节长,也可能是 MB。

在可能的情况下,numpy 操作会尽量避免复制数据缓冲区。索引时,如果可能,它将返回一个 view。我认为该文档比较了 View 和副本。

但是 View 不同于 Python 引用。共享引用意味着两个变量(或列表或字典中的指针)指向同一个 Python 对象。 view 是一个不同的数组对象,但它与另一个数组共享数据缓冲区。副本有自己的数据缓冲区。

在你的例子中:

A = np.random.rand(10, 20)

A 是一个指向数组对象的变量。该对象有一个包含 200 个 float (200*8 字节)的数据缓冲区。

A = 2 * A  # Operation 1: Is a copy of A made, and a reference assigned to A?

2*A 使用新的数据缓冲区创建一个新对象。它的任何数据值都不能与原始 A 共享。 A=... 重新分配 A 变量。旧的 A 对象“丢失”,最终内存被垃圾回收。

B = 2 * A  # Operation 2: Does B get a completely different copy of A?

这个2*A 操作新的A 数组。该对象被分配给 BA 保持不变。

C = A      # Operation 3: Does C get a reference to A?

是的,这只是正常的 Python 赋值。 CA 引用相同的对象。 id(C)==id(A).

B = A[1,:]  #  B is a view

B 是对新数组对象的引用。但是该对象与 A 共享数据缓冲区。这是因为只需从不同的点开始并使用不同的 shape 即可在缓冲区中找到所需的值。

A[0, :] = 3

此 LHS 切片将更改 A 值的子集。它类似于:

B = A[0, :]
B = 3

但是 LHS 切片和 RHS 切片之间存在细微差别。在 LHS 上,您必须更加注意何时获得副本而不是 View 。我尤其在 A[idx1,:][:,idx2] = 3 这样的表达式中看到了这一点。

D = A * B * C 

在像这样的计算中生成了多少中间副本的详细信息隐藏在 numpy C 代码中。最安全的做法是假设它执行类似以下操作:

temp1 = A*B
temp2 = temp1*C
D = temp2
(temp1 goes to garbage)

对于普通计算来说,不必担心这些细节。如果您真的追求速度,您可以对替代方案执行 timeit。偶尔我们会收到关于操作产生内存错误的问题。进行搜索以获取有关这些的更多详细信息。

关于python - Numpy:每个操作的内存分配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33528793/

相关文章:

python - 与请求(python 2.7)一样获取图像文件,然后使用帖子发送到服务器

python - 二维数组索引

python - 更改列时出现稀疏效率警告

Python 不导入 Leap Motion 库

python - 迭代数据框中的行以查找索引、jupyter 中列中的值并在 csv 文件中打印报告

python - 如何使用 python 遍历 webapp RequestHandler 中的所有请求 header ?

python - 如何截断 numpy 数组中大于指定值的值?

python - 如果满足条件但在列中指定了条件,则 Pandas 滚动总和

python - 如何获取每行中 n 个最后/第一个 True 的 NumPy 数组

python - 需要帮助解压缩存储在 Aztec 条形码中的 zlib 数据(德国铁路票)