关于python:array_a = array_b [:]但更改了更改b以及(numpy)

array_a = array_b[:] but changing a changes b aswell (numpy)

抱歉,这个问题出现在这里之前,设置两个数组相等但解决方案不起作用,我不知道为什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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)

当我设置测试矩阵[1]=42时,"零矩阵"也会改变。

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


这就是代码中表示test_matrix是"视图"的注释的含义。视图没有自己的数据副本。相反,它共享原始数组的基础数据。视图不必是整个数组的,但可以是数组的小部分。如果视图是跨步的,这些子部分甚至不需要是连续的。如。

1
2
3
4
5
6
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

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

注意,并非所有的索引操作都会创建视图。如。

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

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

当一个对象提供了一种访问另一个对象的方法(读或写)时,它通常被称为"视图对象"。在这种情况下,对这个视图对象的访问通过读和写都被转移到另一个对象。

这是numpy对象相对于"普通"python对象的一个特性。

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


使用copy复制numpy数组:

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

numpy数组和python列表在这方面的行为有所不同。