如何将Fortran输出的PETSc mpiaij格式ASCII稀疏矩阵导入Python?
优雅解析PETSc ASCII格式矩阵到Python的方法
针对你遇到的mpiaij矩阵导入Python的问题,这里有两个实用且优雅的解决方案,从原生工具到手动解析都覆盖到了:
方法一:用petsc4py直接读取(最推荐)
其实petsc4py本身完全支持读取PETSc的ASCII格式矩阵,这应该是最省心的方式,不需要自己写解析逻辑,还能保留矩阵的原生属性。试试这段代码:
import petsc4py petsc4py.init() from petsc4py import PETSc # 初始化并读取ASCII矩阵文件 A = PETSc.Mat().create() # 替换成你的实际矩阵文件名 A.load('matrix.ascii', PETSc.Mat.FileMode.READ) # 若需要转换成scipy稀疏矩阵方便后续分析(比如用scipy的线性代数工具) import scipy.sparse as sp scipy_sparse_matrix = sp.csr_matrix(A.getValuesCSR())
这个方法的优势在于完全利用PETSc的原生IO能力,避免手动解析可能出现的格式兼容问题,而且如果你的矩阵是分布式的,还能保留其分布式结构,方便后续用petsc4py做进一步计算。
方法二:手动正则解析(当petsc4py读取有问题时)
如果因为某些原因petsc4py读取不顺利,我们可以用正则表达式精准提取ASCII文件中的行号、列号和数值,然后构建scipy稀疏矩阵。针对你给出的格式,这段代码应该能完美适配:
import re import scipy.sparse as sp # 定义匹配行和元素的正则表达式 row_regex = re.compile(r'row (\d+):(.*)') elem_regex = re.compile(r'\((\d+), ([\d.e+-]+)\)') rows = [] cols = [] values = [] with open('matrix.ascii', 'r') as f: for line in f: # 跳过开头的描述行 if line.startswith('Mat Object'): continue # 匹配当前行的行号和元素内容 row_match = row_regex.match(line.strip()) if not row_match: continue row_idx = int(row_match.group(1)) elem_content = row_match.group(2) # 逐个提取该行的非零元素 for elem_match in elem_regex.finditer(elem_content): col_idx = int(elem_match.group(1)) val = float(elem_match.group(2)) rows.append(row_idx) cols.append(col_idx) values.append(val) # 构建CSR格式的稀疏矩阵 max_row = max(rows) + 1 max_col = max(cols) + 1 final_matrix = sp.csr_matrix((values, (rows, cols)), shape=(max_row, max_col))
注意事项
- 如果你的ASCII文件是由多个MPI进程分别输出的,可能需要先合并所有进程的输出文件,再进行解析。
- 正则表达式已经适配了科学计数法(比如
9.37151e-05),不用担心数值格式问题。
内容的提问来源于stack exchange,提问作者Maurice
相关产品推荐
相关产品推荐

