我尝试了以下内容:
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]
答案 0 :(得分:2)
简而言之,区别在于:
... = p[]
)会尽可能为数据创建新视图。p[] = ...
)将elemets复制到数组中。长篇故事:
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
数据只是一块内存。 p
指向此记忆的开头,y
指向中间某处。 (他们不仅仅是"指向"还包含有关维度和谁拥有数据的其他信息,但这在这里并不重要。)
重要的是要认识到数组仅指向其关联数据的开头。然后它只使用维度和步长(步幅)将数据解释为向量,矩阵等。记住:一个数组 - 一个指针。
p[0,:] = p[1,:]
这里我们将p的一部分分配给数组的另一部分。为了获得预期的行为,p
的不同部分需要指向同一数据块。这是不可能的(但是通过巧妙地操纵步幅可以以有限的方式实现类似的东西)。而是复制数据。