python – 从numpy数组中提取对角块
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 从numpy数组中提取对角块,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3051字,纯文字阅读大概需要5分钟。
内容图文
![python – 从numpy数组中提取对角块](/upload/InfoBanner/zyjiaocheng/799/593a4c07acfd4615bc22eeed94816186.jpg)
我正在寻找一种简洁的方法来提取大小为2×2的对角块,它位于(2N)x(2N)numpy数组的主对角线上(也就是说,会有N个这样的块).这概括了numpy.diag,它沿着主对角线返回元素,人们可能会认为它是1×1块(当然numpy并不以这种方式表示它们).
为了更广泛地说明这一点,人们可能希望从(MN)x(MN)阵列中提取N个MxM块.这似乎是scipy.linalg.block_diag的补充,在How can I transform blocks into a blockdiagonal matrix (NumPy)中得到了很好的讨论,从block_diag将它们放置的地方拉出块.
借用the solution to that question的代码,以下是如何设置的:
>>> a1 = np.array([[1,1,1],[1,1,1],[1,1,1]])
>>> a2 = np.array([[2,2,2],[2,2,2],[2,2,2]])
>>> a3 = np.array([[3,3,3],[3,3,3],[3,3,3]])
>>> import scipy.linalg
>>> scipy.linalg.block_diag(a1, a2, a3)
array([[1, 1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 2, 2, 2, 0, 0, 0],
[0, 0, 0, 2, 2, 2, 0, 0, 0],
[0, 0, 0, 2, 2, 2, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 3, 3, 3],
[0, 0, 0, 0, 0, 0, 3, 3, 3],
[0, 0, 0, 0, 0, 0, 3, 3, 3]])
然后,我们希望有一个像这样的功能
>>> A = scipy.linalg.block_diag(a1, a2, a3)
>>> extract_block_diag(A, M=3)
array([[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]],
[[2, 2, 2],
[2, 2, 2],
[2, 2, 2]],
[[3, 3, 3],
[3, 3, 3],
[3, 3, 3]]])
为了继续用numpy.diag进行类比,人们可能还希望提取非对角线块:它们在第k个块对角线上的N – k. (顺便说一下,block_diag的扩展允许块放在主对角线之外肯定会有用,但这不是这个问题的范围.)在上面的数组的情况下,这可能会产生:
>>> extract_block_diag(A, M=3, k=1)
array([[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]],
[[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]])
我看到this question中使用的stride_tricks旨在产生类似于这个功能的东西,但我知道跨步操作在字节级别,这听起来不太合适.
通过动机,这源于我希望提取协方差矩阵的对角元素(即方差)的情况,其中元素本身不是标量而是2×2矩阵.
编辑:根据the suggestion from Chris,我做了以下尝试:
def extract_block_diag(A,M,k=0):
"""Extracts blocks of size M from the kth diagonal
of square matrix A, whose size must be a multiple of M."""
# Check that the matrix can be block divided
if A.shape[0] != A.shape[1] or A.shape[0] % M != 0:
raise StandardError('Matrix must be square and a multiple of block size')
# Assign indices for offset from main diagonal
if abs(k) > M - 1:
raise StandardError('kth diagonal does not exist in matrix')
elif k > 0:
ro = 0
co = abs(k)*M
elif k < 0:
ro = abs(k)*M
co = 0
else:
ro = 0
co = 0
blocks = np.array([A[i+ro:i+ro+M,i+co:i+co+M]
for i in range(0,len(A)-abs(k)*M,M)])
return blocks
对于上面的数据,将返回以下结果:
D = extract_block_diag(A,3)
[[[1 1 1]
[1 1 1]
[1 1 1]]
[[2 2 2]
[2 2 2]
[2 2 2]]
[[3 3 3]
[3 3 3]
[3 3 3]]]
D = extract_block_diag(A,3,-1)
[[[0 0 0]
[0 0 0]
[0 0 0]]
[[0 0 0]
[0 0 0]
[0 0 0]]]
解决方法:
作为起点,你可以使用类似的东西
>>> a
array([[1, 1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 2, 2, 2, 0, 0, 0],
[0, 0, 0, 2, 2, 2, 0, 0, 0],
[0, 0, 0, 2, 2, 2, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 3, 3, 3],
[0, 0, 0, 0, 0, 0, 3, 3, 3],
[0, 0, 0, 0, 0, 0, 3, 3, 3]])
>>> M = 3
>>> [a[i*M:(i+1)*M,i*M:(i+1)*M] for i in range(a.shape[0]/M)]
[array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]), array([[2, 2, 2],
[2, 2, 2],
[2, 2, 2]]), array([[3, 3, 3],
[3, 3, 3],
[3, 3, 3]])]
内容总结
以上是互联网集市为您收集整理的python – 从numpy数组中提取对角块全部内容,希望文章能够帮你解决python – 从numpy数组中提取对角块所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。