NumPy中明显不一致的引用行为

2024-04-26 00:02:36 发布

您现在位置:Python中文网/ 问答频道 /正文

当从2D numpy数组中的另一行引用给定行时,我注意到在我看来是意外的行为

a = np.array([[1,2], [3, 4]])
a[1] = a[0]
a[1] += 100

在此操作之后,a将等于:

array([[  1,   2], [101, 102]])

我不明白为什么不考虑对a[0]的引用,而只修改了a[1]。尤其是对于Python列表,情况并非如此:

a = [[1,2], [3,4]]
a[1] = a[0]
a[1][1] = 999

这将给a

[[1, 999], [1, 999]]

Tags: numpy列表np情况数组array行时
1条回答
网友
1楼 · 发布于 2024-04-26 00:02:36

任何not-object数据类型的NumPy数组不包含引用。因此,当您设置a[1] = a[0]时,它只是将a[0]的内容复制到a[1]。这意味着任何对a[1]a[0]的后续赋值都不会改变另一个。你知道吗

另一方面,当您有a[1] = a[0]时,列表不会复制,它只是在a[1]中插入对a[0]的引用。这意味着对a[1]a[0]的赋值也会改变另一个。你知道吗

要点可能是:不要认为NumPy数组包含引用。它实际上不是嵌套的“数组”,即使是多维的。它总是一个一维数组,使用“跨步”来“显示多维”。你知道吗


在这里比较“身份”可能会有所帮助。这有点复杂,因为NumPy不处理引用,而是处理内存缓冲区。但是,NumPy提供了一个检查共享内存的功能:

>>> import numpy as np
>>> a = np.array([[1,2], [3, 4]])
>>> a[1] = a[0]
>>> np.shares_memory(a[1], a[0])  # the arrays don't share memory
False

>>> a = [[1,2], [3,4]]
>>> a[1] = a[0]
>>> a[1] is a[0]                  # they are the same object
True

请注意,如果只“查看”NumPy数组而不将其指定给数组,则情况有所不同。对NumPy数组的赋值就是复制的内容。这是因为,如我所说,NumPy数组不存储引用,它只存储元素。因此,可以将视图插入数组,但不能将视图作为视图插入NumPy数组。你知道吗

例如:

>>> a = np.array([[1,2], [3, 4]])
>>> b = a[0]                      # b is now a view into "a"
>>> np.shares_memory(b, a[0])
True

>>> a[1] = b
>>> np.shares_memory(b, a[1])     # a[1] is not a view into "a[0]".
False

相关问题 更多 >