numpy:按引用传递对自身不起作用

时间:2017-07-06 11:06:56

标签: python numpy pass-by-reference

我尝试了以下内容:

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]

1 个答案:

答案 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的不同部分需要指向同一数据块。这是不可能的(但是通过巧妙地操纵步幅可以以有限的方式实现类似的东西)。而是复制数据。