2014-12-20 81 views
-1

什么可能是错的分配如下,它应该如何固定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不在分配前后进行更改。

+0

什么是n,什么是anew? (你可以给我们一个失败的例子) –

+1

我认为他们对这个举行是挑剔的。 'unutbu'理解了这个问题,并给出了一个很好的答案。仍然不难编辑这个例子 - 较小的'n',定义一个'Anew',指定'Adash'中的预期变化。 – hpaulj

+0

可惜它被搁置,因为这是我在这里很少看到的东西。有关np.ix_的其他问题的任何链接?由于我找不到很多,我认为这个答案应该在那里。它不是一个调试问题,而是一个概念问题 - 这种类型的索引出现在很多机器学习应用程序中。关于切片和高级整数索引尽管丰富的答案在这里是无用的。我对@unutbu的回答非常满意,并且他们两次都很高兴,他们明白了我所要求的而不挑剔n的值,例如 – methane

回答

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一个视图,然后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)),修改tempAdash永远不会被修改。由于没有对temp的引用,因此临时的新创建的数组会被垃圾收集。


PS。语句结尾的分号在Python中是不必要的。

+0

谢谢!我很困惑,那为什么如下:U [:,a] = np.dot(U [:,a],V);工作很好,U更新?这里V只是一个适当大小的数组。 – methane

+0

'U [...] val'调用'U .__ setitem__',所以它修改'U'。当第一组括号返回一个副本而不是一个视图时,这是两组括号的引起问题。 – unutbu

+0

啊,我非常感谢!对于更有效地表达U [:,a] = np.dot(U [:,a],V),你有任何建议吗?我不知道np.ix函数 - 非常有用。 – methane