2014-12-20 123 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