array_a = array_b [:]但同时也更改了b(numpy)

时间:2019-02-12 16:01:11

标签: python python-3.x numpy

抱歉,这个问题是在这里Setting two arrays equal之前提出的 但是解决方案不起作用,我也不知道为什么。

import numpy as np

zero_matrix = np.zeros((3,3)) # 3x3 zero matrix

test_matrix = zero_matrix[:] # test_matrix is a view of zero_matrix. Without [:] it would be same object
print (zero_matrix)
print ()
print (test_matrix)
print ()
print(id(test_matrix))
print ()
print(id(zero_matrix))
print ()

test_matrix[1] = 42

print (test_matrix)
print ()
print (zero_matrix)

当我设置test_matrix [1] = 42时,“ zero_matrix”也会更改。

我不明白为什么原因,因为两者都有不同的对象ID。

3 个答案:

答案 0 :(得分:1)

使用copy复制您的numpy数组:

zero_matrix = np.zeros((3,3))
test_matrix = zero_matrix.copy()
test_matrix[1] = 42
print(zero_matrix)
print(test_matrix)

在这一点上,numpy数组和python列表的行为有所不同。

答案 1 :(得分:1)

它们确实具有两个不同的对象ID,但是,正如您自己写道:test_matrixzero_matrix的视图。

当一个对象提供一种访问另一个对象(通过读取或写入)的方式时,通常称为“视图对象”。在这种情况下,通过读取和写入,对该视图对象的访问都将偏转到另一个对象。

那是numpy对象与“普通” python对象相对的专业。

但是,即使python也具有这些对象,但是除非明确要求,否则它们不会使用它们。

答案 2 :(得分:1)

这就是代码中的注释表示test_matrix是“视图”的意思。视图没有自己的数据副本。而是共享原始数组的基础数据。视图不必是整个数组的视图,而可以是数组的小部分。如果跨越视图,这些子部分甚至不需要是连续的。例如。

a = np.arange(10)
b = a[::2] # create a view of every other element starting with the 0-th
assert list(b) == [0, 2, 4, 6, 8]
assert a[4] == 4
b[2] = -1
assert a[4] == -1

视图功能强大,因为它们无需复制大量数据即可进行更复杂的操作。不需要一直复制数据可能意味着某些操作比原先的操作要快。

当心,并非所有索引操作都会创建视图。例如。

a = np.arange(10, 20)
b = a[[1,2,5]]
assert list(b) == [11, 12, 15]
b[0] == -1
assert a[1] != -1