python - numpy 将 2D 矩阵 reshape 为对称矩阵数组(3D 数组),无需循环

标签 python numpy

考虑我有一个以下形式的二维数组

D = [
 [A11,A21,A31,A22,A23,A33],
 [B11,B21,B31,B22,B23,B33],
 [C11,C21,C31,C22,C23,C33]
]

其中每个D[i]都是对称矩阵的表示。

对称矩阵可以 reshape 为

[
 [[A11,A21,A31
   A21,A22,A23
   A31,A23,A33]],

 [[B11,B21,B31
   B21,B22,B23
   B31,B23,B33]],

 [[C11,C21,C31
   C21,C22,C23
   C31,C23,C33]]
]

所以 D[i] 是第 i 个对称矩阵(带对角线)的下三角部分的值列表

通过以result = np.zeros(3,3,3)开始执行迭代循环很容易,然后我们填充条目。

请注意,我不需要计算相关性等,因为协方差矩阵的值已经给出。我只是想在一定的约束下将 2D reshape 为 3D(对称且索引正确)

我想知道是否有更有效的方法而不使用循环?谢谢

最佳答案

您可以通过 3 个步骤实现这一目标(为简单起见,从一个对称矩阵开始):

假设有一个向量 d0 = D[0]

d0 = D[0]  # [A11,A21,A31,A22,A23,A33]

首先创建一个空矩阵

r = np.zeros([3, 3])  # note: any size will do

将 d0 分配给矩阵的上部

upper_tri = ~np.tri(3, 3, -1, dtype=bool)
# [[ True,  True,  True],
#  [False,  True,  True],
#  [False, False,  True]]

r[upper_tri] = d0
# [[A11,A21,A31],
#  [ 0 ,A22,A23],
#  [ 0 , 0 ,A33]]

然后转置结果并将其分配给自身,但应用仅匹配下三角形的掩码:

lower_tri = ~upper_tri
r[lower_tri] = r.T[lower_tri]
# [[A11,A21,A31
#   A21,A22,A23
#   A31,A23,A33]]
<小时/>

您可以使用广播来扩展这种方法,但这非常棘手。您需要转置每个输入和输出矩阵。这是因为适用于标量的方法(例如,这里 A21 是单个标量)也适用于向量

d0 = D.T  # [ [A11, B11, C11], [A21, B21, C21], [A31, B31, C31]... ]

N = 3  # as batch size to avoid confusion
r = np.zeros([3, 3, N])

upper_tri = ~np.tri(3, 3, -1, dtype=bool)  # same as before
r[upper_tri] = d0

lower_tri = ~upper_tri
r[lower_tri] = r.transpose([1, 0, 2])[lower_tri]

r = r.transpose([2, 0, 1])

关于python - numpy 将 2D 矩阵 reshape 为对称矩阵数组(3D 数组),无需循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58701017/

相关文章:

python - 将 PNG 图像文件转换为像素行以保存在数据框中

python - numpy 选择不同长度的每一行

python - 从外部模块调用 gimp-fu 函数

python - 在 django shell 中连接到不同的数据库

python - pandas 中行之间的减法 - python

python - 规范化向量在 Numpy 中产生 nan

python - Selenium:driver.get_cookies() 返回不完整的 cookie 列表

python - 如何在Elasticsearch中保存坐标以建立索引并在Kibana中使用它们

python - 基于多种条件过滤像素

python - 从 pandas 数据框中保存的分组数据有效地创建大量直方图