【问题标题】:numpy: pass by reference does not work on itselfnumpy:按引用传递对自身不起作用
【发布时间】:2017-07-06 11:06:56
【问题描述】:

我尝试了以下方法:

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]

【问题讨论】:

    标签: python numpy pass-by-reference


    【解决方案1】:

    简而言之,区别:

    • 如果可能,访问数组的切片 (... = 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 指向中间某处。 (它们不仅“指向”,还包含有关维度和谁拥有数据的附加信息,但这在这里并不重要。)

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

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

    【讨论】:

      猜你喜欢
      • 2015-08-26
      • 2011-02-19
      • 1970-01-01
      • 2018-01-02
      • 2012-02-10
      • 2015-12-18
      • 1970-01-01
      • 2011-05-08
      • 2013-04-12
      相关资源
      最近更新 更多