[英]diagonalize multiple vectors using numpy
假設我有一個形狀為 (2,3) 的矩陣,我需要一次將所有 2 個向量的 3 元素向量對角化為形狀 (3,3) 的矩陣。 也就是說,我需要返回形狀為 (2,3,3) 的矩陣。 如何優雅地使用 Numpy 做到這一點?
given data = np.array([[1,2,3],[4,5,6]])
i want the result [[[1,0,0],
[0,2,0],
[0,0,3]],
[[4,0,0],
[0,5,0],
[0,0,6]]]
謝謝
tl;博士,我的單行: mydiag=np.vectorize(np.diag, signature='(n)->(n,n)')
我想這里的“對角化”是指“應用 np.diag”。 作為線性代數的老師,這讓我有點發癢。 由於“對角化”具有特定含義,但並非如此(它正在計算特征向量和值,並從那里寫入 M=P⁻¹ΛP。您無法從您擁有的輸入中做到這一點)。
所以,我想如果輸入矩陣是
[[1, 2, 3],
[9, 8, 7]]
您想要的 output 矩陣是
[[[1, 0, 0],
[0, 2, 0],
[0, 0, 3]],
[[9, 0, 0],
[0, 8, 0],
[0, 0, 7]]]
如果沒有,您可以忽略此答案 [編輯:與此同時,您對此進行了准確的解釋。 所以你可以繼續閱讀]。
有很多方法可以做到這一點。 我的一個班輪將是
mydiag=np.vectorize(np.diag, signature='(n)->(n,n)')
它構建了一個可以執行您想要的新功能(它將輸入解釋為一維數組的列表,調用每個數組的 np.diag 以獲取二維數組,並將每個二維數組放入 numpy 數組中,從而得到一個3D陣列)
然后,您只需調用mydiag(M)
矢量化的優點之一是它使用 numpy 廣播。 換句話說,循環在 C 中執行,而不是在 python 中執行。 換句話說,它更快。 好吧,它應該是(在小矩陣上,它實際上比邁克爾的方法慢 - 在評論中;在大矩陣上,它具有完全相同的速度。這令人沮喪,因為 einsum doc 本身指定它犧牲了廣播)。
另外,它是單線的,除了在論壇上吹牛之外沒有其他興趣。 但是,我們到了。
這是索引的一種方法:
out = np.zeros(data.shape+(data.shape[-1],), dtype=data.dtype)
x,y = np.indices(data.shape).reshape(2, -1)
out[x,y,y] = data.ravel()
output:
array([[[1, 0, 0],
[0, 2, 0],
[0, 0, 3]],
[[4, 0, 0],
[0, 5, 0],
[0, 0, 6]]])
我們使用數組索引來精確抓取對角線上的那些元素。 請注意,數組索引允許在索引之間廣播,因此我們讓 index1 包含數組的索引,而 index2 包含對角元素的索引。
index1 = np.arange(2)[:, None] # 2 is the number of arrays
index2 = np.arange(3)[None, :] # 3 is the square size of each matrix
result = np.zeros((2, 3, 3))
result[index1, index2, index2] = data
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.