什麼可能是錯的分配如下,它應該如何固定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