修改:我发现问题归结为:
如果您运行此代码:
A = ones((10,4))
view = A[:,1]
view.fill(7)
A
或
A = ones((10,4))
view = A[:,1:3]
view.fill(7)
A
你会看到A的列改变
如果你运行:
A = ones((10,4))
view = A[:,(1,2)]
view.fill(7)
A
对A没有副作用。这种行为是故意还是错误?
我有一个函数来计算我必须旋转矩阵中x,y点的某些列的量。该函数只接受一个输入 - 矩阵垫:
def rotate(mat):
在函数中,我创建视图以便更轻松地使用每个部分:
rot_mat = mat[:,(col,col+1)]
然后,我计算一个旋转角度并将其应用回我之前创建的视图:
rot_mat[row,0] = cos(rot)*x - sin(rot)*y
rot_mat[row,1] = sin(rot)*x + cos(rot)*y
如果我在程序的主体中执行此操作,对rot_mat视图的更改将传播到原始矩阵mat。当我把它变成一个函数时,视图停止对原始矩阵产生副作用。这是什么原因,有没有办法绕过它?我还应该注意,它并没有改变函数本身。最后,我只是尝试返回垫子,但没有做出任何改变。
功能的完整代码:
def rotate(mat):
# Get a reference shape
ref_sh = 2*random.choice(range(len(filelist)))
print 'Reference shape is '
print (ref_sh/2)
# Create a copy of the reference point matrix
ref_mat = mat.take([ref_sh,ref_sh+1],axis=1)
# Calculate rotation for each set of points
for col in range(len(filelist)):
col = col * 2 # Account for the two point columns
rot_mat = mat[:,(col,col+1)]
# Numerator = sum of wi*yi - zi*xi
numer = inner(ref_mat[:,0],rot_mat[:,1]) - inner(ref_mat[:,1],rot_mat[:,0])
# Denominator = sum of wi*xi + zi*yi
denom = inner(ref_mat[:,0],rot_mat[:,0]) + inner(ref_mat[:,1],rot_mat[:,1])
rot = arctan(numer/denom)
# Rotate the points in rot_mat. As it's a view of mat, the effects are
# propagated.
for row in range(num_points):
x = rot_mat[row,0]
y = rot_mat[row,1]
rot_mat[row,0] = cos(rot)*x - sin(rot)*y
rot_mat[row,1] = sin(rot)*x + cos(rot)*y
return mat
答案 0 :(得分:0)
执行view = A[:,(1,2)]
时,您正在使用高级索引(Numpy manual: Advanced Indexing),这意味着数组返回副本,而不是视图。它是高级的,因为您的索引对象是一个“包含至少一个序列”的元组(序列是元组(1,2)
)。您的案例中的总显式选择对象obj
将等于(slice(None), (1,2))
,即A[(slice(None), (1,2))]
返回与A[:,(1,2)]
相同的内容。
正如上面的larsmans所暗示的那样,__getitem__
和__setitem__
似乎对高级索引的行为有所不同,这是有道理的,因为为副本赋值不会有用(副本不会被存储)