繁体   English   中英

使用 numpy 对多个向量进行对角化

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM