创建块矩阵/数组时为何报错?(SciPy与NumPy相关)
问题分析与解决
报错原因
你遇到的ValueError: row, column, and data arrays must be 1-D,核心问题是**data参数格式不符合BSR矩阵要求**:
- 虽然BSR支持块矩阵,但
data需要是三维NumPy数组(形状为(块数量, 块行数, 块列数)),而非Python列表包裹的二维数组。 - 你传入的
[M1, M2]是列表,SciPy无法将其识别为合法的块数据结构,因此触发维度检查错误。
修正后的BSR矩阵代码
将data转换为三维NumPy数组即可修复报错,同时确保row/col为NumPy数组(避免隐式类型问题):
import scipy as sp import numpy as np def H1(M1, M2, N): # 将多个块堆叠为三维数组:(2, 2, 2) → 2个块,每个块2×2 data = np.stack([M1, M2]) row = np.array([0, 1]) # 块对应的行索引(每个块占2行) col = np.array([0, 0]) # 块对应的列索引(每个块占2列) blocksize = (2, 2) # 注意:N必须是blocksize的整数倍(这里6=2×3,符合要求) return sp.sparse.bsr_matrix((data, (row, col)), blocksize=blocksize, shape=(N, N)).toarray() M1 = np.array([[1,1], [1,1]]) M2 = np.array([[2,2], [2,2]]) print(H1(M1, M2, 6))
300×300块矩阵的更优实现
针对你沿主对角线放置M1、M1下方放置M2的需求,推荐利用稀疏矩阵的块操作工具,既高效又简洁:
场景1:主对角线全为M1,下方次对角线全为M2
如果是要构建主对角线有150个M1(300/2=150),每个M1正下方对应位置放M2,可通过以下方式实现:
import scipy.sparse as sps import numpy as np M1 = np.array([[1,1],[1,1]]) M2 = np.array([[2,2],[2,2]]) block_count = 150 # 300×300矩阵对应150个2×2块 # 构建主对角线的M1块矩阵 diag_matrix = sps.block_diag([M1]*block_count, format='bsr') # 构建下方次对角线的M2块矩阵 off_diag_data = np.stack([M2]*(block_count-1)) off_diag_row = np.arange(1, block_count) off_diag_col = np.arange(block_count-1) off_diag_matrix = sps.bsr_matrix( (off_diag_data, (off_diag_row, off_diag_col)), blocksize=(2,2), shape=(300,300) ) # 合并两个稀疏矩阵 result = diag_matrix + off_diag_matrix # 如需查看稠密矩阵,执行:print(result.toarray())
场景2:仅单个M1在对角、单个M2在其下方
如果只需要在(0-1行,0-1列)放M1,(2-3行,0-1列)放M2,其余为0,直接用修正后的BSR代码即可,注意保持N=300,此时除指定块外其余位置均为0,稀疏矩阵存储会比稠密矩阵节省大量内存。
内容的提问来源于stack exchange,提问作者user971706
相关产品推荐
相关产品推荐

