你是对的,B指向原始数组并且A(最后)是数组的转置视图。
这里的关键点是让很多人感到困惑的事情:每当您使用=不使用索引(例如,A = <anything>)为变量分配新值时,它会导致该变量指向新位置,但不会改变先前保存在该变量中的数据。
这是正在发生的事情的注释版本:
A = np.array([[1,2,3],[4,5,6]])
# create the array [[1,2,3],[4,5,6]] at some location in memory
# (let's call it loc 1)
# point variable A to loc 1
B = A
# point variable B to the same location as A (loc 1)
A = A.T
# right-hand side:
# - get the array that A currently points to (from loc 1)
# - create a transposed view of this array and store the view
# somewhere in memory (let's call it loc 2)
# left-hand side: set variable A to point to loc 2
# Note: the `=` assignment does not alter the object at loc 1; instead,
# it points A to the new object that was created on the right-hand side
A[0,1]= -1
# Push the value -1 into position (0, 1) of the object that A
# currently points to, i.e., the view at loc 2. This updates
# the A view, but also propagates back to the original,
# un-transposed array at loc 1 (which B still points to).
# Note that the last two lines are equivalent to this:
X = A.T # doesn't transpose B
X[0,1]= -1 # propagates through view back to B
# i.e., the A.T could have been assigned to anything, e.g. a new
# variable X. When you do an assignment with `=`, it creates a new
# variable every time, even if it happens to have the same name as
# an old one, as in your case.
这是更改可变数据并获得意外副作用的一般问题。考虑它的最简单方法是裸变量赋值 ( A = <something>)永远不会改变A当前指向的基础数据。相反,它只是导致A指向新的地方。另一方面,分配A[index] = <something>或A.attribute = <something>使用A.data_altering_method(...) 将改变 A 所指向的底层对象,因此指向同一对象的任何其他对象也将看到更改。
在您的情况下,您所做的唯一改变基础数据的事情是A[0,1]= -1,并且确实传播到B. A = A.T没有改变基础数据,它只是指出A了一些新的东西(恰好是原始数据的新视图)。所以对A变量的更改没有传播到B. 但是,创建视图而不是副本有点令人惊讶 A = A.T,因此以后的更改会A影响B. 你中间的两行相当于B.T[0,1] = -1.
这些答案也有帮助: