python - numpy 将 2D 矩阵重塑为对称矩阵数组(3D 数组),无需循环
问题描述
考虑我有一个以下形式的二维数组
D = [
[A11,A21,A31,A22,A23,A33],
[B11,B21,B31,B22,B23,B33],
[C11,C21,C31,C22,C23,C33]
]
其中每个D[i]
都是对称矩阵的表示。
对称矩阵可以重新整形为
[
[[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 重塑为 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])
推荐阅读
- javascript - 与另一个对象数组交叉引用
- r - 从R中的列表中替换列表的字符串
- javascript - 需要帮助正确显示明天的日期,javascript
- html - 使叠加层后面的图像可点击
- iis - 核心 Web API 作为 IIS 中的虚拟目录
- reactjs - 在 React 中使用自定义组件创建 PDF
- typescript - 如何在 TypeScript 中使用动态键定义对象类型?
- php - 查询失败:错误:编码“UTF8”的字节序列无效:在 Postgresql 中插入图像时出现 0xff
- java - 无法与 SpringORM 和 Hibernate 建立 JDBC 连接
- python - 借助另一个文件中的名称拆分文件名并将文本文件保存在目录中