我尝试了以下方法:
p=np.array([[1,1,1],[2,2,2],[3,3,3]])
p[0,:] = p[1,:]
y = p[1,:]
print(p)
p[1,1] = 4
print(p)
print(y)
如您所见,输出为:
[[2 2 2]
[2 2 2]
[3 3 3]]
[[2 2 2]
[2 4 2]
[3 3 3]]
[2 4 2]
所以当我将 p
的第二行分配给 y
时,它是通过引用传递的。当我将 p
的第二行分配给 p
的第一行时,它是通过副本传递的。为什么会这样?
我期望的输出是:
[[2 2 2]
[2 2 2]
[3 3 3]]
[[2 4 2]
[2 4 2]
[3 3 3]]
[2 4 2]
最佳答案
简而言之,区别:
- 如果可能,访问数组的一部分 (
... = p[]
) 会创建一个新的数据 View 。 - 分配给数组的一部分 (
p[] = ...
) 将元素复制到数组中。
长话短说:
p = np.array([[1,1,1],[2,2,2],[3,3,3]])
p
保存原始数据。
y = p[1,:]
让您可以查看 p
持有的数据(您可以通过查看 y.base< 来验证这一点
,是p
)。这不是对数组的赋值,但是y
是一个全新的对象,它与p
共享数据。可以这样想:
Data: [1, 1, 1, 2, 2, 2, 3, 3, 3]
^ ^
p y
数据只是一 block 内存。 p
指向这段内存的开头,y
指向中间的某个地方。 (它们不只是“指向”,还包含有关维度和谁拥有数据的附加信息,但这在这里并不重要。)
重要的是要认识到数组仅指向其关联数据的开头。然后它简单地使用维度和步长(步幅)将数据解释为向量、矩阵等。记住:一个数组 - 一个指针。
p[0,:] = p[1,:]
这里我们将 p 的一部分分配给数组的另一部分。要获得预期的行为,p
的不同部分需要指向相同的数据 block 。这是不可能的(但可以通过巧妙地操纵步幅以有限的方式实现类似的事情)。相反,数据被复制。
关于python - numpy:通过引用传递对自身不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44947211/