以下作业可能出现什么问题?如何修复
n = 1000
a = np.array ([8,9,0])
Anew= np.random.random((n,n))
Adash= np.zeros((n,n))+ np.diag(np.diag(Anew))
S = Anew[a,:][:,a]
Adash[a,:][:,a]= S
这里S是一个非零数组,Anew也是一些与Adash大小相同的非零数组,但Adash在赋值前后不会改变。
答案 0 :(得分:2)
高级索引会返回副本:
Adash[a,:]
正在使用"advanced integer indexing"。与基本切片相反,高级索引始终返回副本。所以
Adash[a,:][:,a] = ...
正在修改Adash
本身的副本,而不是视图。
为了增加对伤害的侮辱,没有提及Adash[a,:]
返回的副本,因此副本的修改也会丢失。
您可以使用numpy.ix_:
Adash[np.ix_(a,a)] = S
例如,
import numpy as np
n = 4
Anew = np.arange(16).reshape(4, 4)
a = np.arange(3)
Adash = np.zeros((n, n)) + np.diag(np.diag(Anew))
S = Anew[a, :][:, a]
Adash[a, :][:, a] = S
print(Adash)
# [[ 0. 0. 0. 0.]
# [ 0. 5. 0. 0.]
# [ 0. 0. 10. 0.]
# [ 0. 0. 0. 15.]]
Adash[np.ix_(a,a)] = S
print(Adash)
# [[ 0. 1. 2. 0.]
# [ 4. 5. 6. 0.]
# [ 8. 9. 10. 0.]
# [ 0. 0. 0. 15.]]
基本切片返回视图:
或者,如果您可以使用基本切片替换整数索引数组a
,那么Adash[slice]
将返回Adash
的视图,然后{ {1}}修改Adash[slice][...] = val
:
Adash
有关Adash[:3, :3] = S
未修改Adash的原因的详情:
使用两组括号称为索引链接。
请注意,当您在没有索引链接的情况下表达分配时,Adash[a,:][:,a] = ...
会被修改,因为Adash
会导致Adash[...] = val
被调用。
相比之下,Adash.__setitem__
调用Adash[a,:][:,a]
会返回一个新数组,我们称之为Adash.__getitem__((a,slice(None)))
,其基础数据是从temp
复制的。然后调用Adash
,修改temp.__setitem__((slice(None), a))
。永远不会修改temp
。由于没有对Adash
的引用,临时的新创建的数组会被垃圾收集。
PS。语句末尾的分号在Python中是不必要的。