numpy中的数组赋值?

时间:2014-12-20 21:59:36

标签: python numpy

以下作业可能出现什么问题?如何修复

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在赋值前后不会改变。

1 个答案:

答案 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中是不必要的。