簡體   English   中英

從沒有 for 循環的 2D 矩陣的行創建對角矩陣

[英]Create diagonal matrix from rows of a 2D matrix without for loop

假設您有一個mxn矩陣 A 並且想要創建 m 個對角矩陣,每個矩陣都來自 A 的行,因此具有形狀nxn 生成的矩陣應具有mxnxn形狀。

我知道一個典型的解決方案是:

result = numpy.stack([numpy.diag(A[i,:]) for i in range(A.shape[0])], axis=0)

我想知道我們是否有可能在不使用循環的情況下獲得相同的結果。

任何想法將不勝感激!

這似乎有效:

result = np.zeros((A.shape[0], A.shape[1], A.shape[1]), dtype=A.dtype)
result[:, range(A.shape[1]), range(A.shape[1])] = A

測試輸入:

A = np.arange(24).reshape(4,6)

Output print(result)

[[[ 0  0  0  0  0  0]
  [ 0  1  0  0  0  0]
  [ 0  0  2  0  0  0]
  [ 0  0  0  3  0  0]
  [ 0  0  0  0  4  0]
  [ 0  0  0  0  0  5]]

 [[ 6  0  0  0  0  0]
  [ 0  7  0  0  0  0]
  [ 0  0  8  0  0  0]
  [ 0  0  0  9  0  0]
  [ 0  0  0  0 10  0]
  [ 0  0  0  0  0 11]]

 [[12  0  0  0  0  0]
  [ 0 13  0  0  0  0]
  [ 0  0 14  0  0  0]
  [ 0  0  0 15  0  0]
  [ 0  0  0  0 16  0]
  [ 0  0  0  0  0 17]]

 [[18  0  0  0  0  0]
  [ 0 19  0  0  0  0]
  [ 0  0 20  0  0  0]
  [ 0  0  0 21  0  0]
  [ 0  0  0  0 22  0]
  [ 0  0  0  0  0 23]]]

不會是最有效的方法,但這樣的事情可能會奏效

import numpy as np

A = np.random.rand(10, 5)

S = np.einsum("ai,ij->aij", A, np.ones((5, 5)))
M = np.eye(5).astype(np.bool)
M = np.repeat(M[None, ...], 10, axis=0)
S[~M]=0
print(S.shape)

您可以嘗試以下我們使用廣播numpy.identity()來獲得所需的結果。

# `arr` is input of size (m, n); for instance,
arr = np.arange(1, 13).reshape(3, -1)   # (3, 4)

# get column size
In [160]: _ , n = arr.shape

# fill the rows from the input, after promoting it to 3D
In [161]: res = np.eye(n, dtype=arr.dtype) * arr[:,np.newaxis]

In [162]: res.shape
Out[162]: (3, 4, 4)

注意:因為我們將(n,n)作為最后兩個維度, 所以 np.identity()也可以工作。

In [171]: res = np.identity(n, dtype=arr.dtype) * arr[:,np.newaxis]

In [172]: res.shape
Out[172]: (3, 4, 4)

另一種方法是使用高級索引,其中首先用零初始化結果數組,然后切出對角元素的索引並用輸入數組填充它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM