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

numpy: pass by reference does not work on itself

我尝试了以下方法:

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[]) 会创建一个新的数据视图。
  • 分配给数组的一部分 (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

数据只是一块内存。 p 指向此内存的开头,而 y 指向中间某处。 (它们不仅 "point" 还包含有关维度和谁拥有数据的其他信息,但这在这里并不重要。)

重要的是要认识到数组仅指向其关联数据的开头。然后它简单地使用维度和步长(步幅)将数据解释为向量、矩阵等。记住:一个数组 - 一个指针。

p[0,:] = p[1,:]这里我们将p的一部分赋值给数组的另一部分。要获得预期的行为,p 的不同部分需要指向同一数据块。这是不可能的(但可以通过巧妙地操纵步幅以有限的方式实现类似的事情)。而是复制数据。