什么可能是错的分配如下,它应该如何固定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是一个非零阵列并重新也是一些非零数组的大小Adash相同,但Adash不在分配前后进行更改。
什么可能是错的分配如下,它应该如何固定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是一个非零阵列并重新也是一些非零数组的大小Adash相同,但Adash不在分配前后进行更改。
高级索引返回副本:
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
一个视图,然后Adash[slice][...] = val
修改Adash
:
Adash[:3, :3] = S
更多关于为什么Adash[a,:][:,a] = ...
不修改Adash:
使用两组括号称为索引cha都进不去。 请注意,当您表达没有索引链接的分配时,Adash
会被修改,因为Adash[...] = val
会导致Adash.__setitem__
被调用。
相比之下,Adash[a,:][:,a]
调用Adash.__getitem__((a,slice(None)))
返回一个新的数组,我们称之为temp
,其基础数据从Adash
复制。然后调用temp.__setitem__((slice(None), a))
,修改temp
。 Adash
永远不会被修改。由于没有对temp
的引用,因此临时的新创建的数组会被垃圾收集。
PS。语句结尾的分号在Python中是不必要的。
什么是n,什么是anew? (你可以给我们一个失败的例子) –
我认为他们对这个举行是挑剔的。 'unutbu'理解了这个问题,并给出了一个很好的答案。仍然不难编辑这个例子 - 较小的'n',定义一个'Anew',指定'Adash'中的预期变化。 – hpaulj
可惜它被搁置,因为这是我在这里很少看到的东西。有关np.ix_的其他问题的任何链接?由于我找不到很多,我认为这个答案应该在那里。它不是一个调试问题,而是一个概念问题 - 这种类型的索引出现在很多机器学习应用程序中。关于切片和高级整数索引尽管丰富的答案在这里是无用的。我对@unutbu的回答非常满意,并且他们两次都很高兴,他们明白了我所要求的而不挑剔n的值,例如 – methane