Python中大数据集关联矩阵与上三角矩阵高效处理优化咨询
问题分析
你的核心问题出在稠密矩阵的内存浪费和逐行循环的低效执行:
- 20000×20000的float64稠密矩阵需要约3GB内存(20000200008字节),远超过必要开销——关联矩阵绝大多数元素是0,完全不需要存储这些零值。
- 逐行遍历5万行数据的Python循环本身就慢,而且你还在每一次循环里重复执行
np.triu和np.flatnonzero,这属于完全无意义的重复计算。
优化方案
一、内存优化:用稀疏矩阵替代稠密矩阵
使用scipy.sparse模块的稀疏矩阵(比如coo_matrix或csr_matrix),只存储非零元素的位置和值,内存占用能降到原来的几百分之一甚至更低。
二、速度优化:批量处理+避免冗余计算
- 直接批量提取所有映射对,生成对称的索引对,无需逐行循环。
- 只处理上三角部分(或下三角),避免重复存储对称位置的元素。
- 读取CSV时指定数据类型为整数,减少内存开销。
优化后代码
import pandas as pd import numpy as np import glob from scipy.sparse import coo_matrix def process_csv(filename): # 读取CSV,指定列类型为整数,减少内存占用 df = pd.read_csv(filename, dtype={'0': int, '1': int}) # 获取所有映射对的数组 rows = df['0'].values cols = df['1'].values # 生成上三角的索引对:保留row<=col的对,交换row>col的对位置 mask = rows <= cols upper_rows = np.concatenate([rows[mask], cols[~mask]]) upper_cols = np.concatenate([cols[mask], rows[~mask]]) # 创建上三角稀疏关联矩阵,用int8存储值(仅需0/1) inc_sparse = coo_matrix( (np.ones(len(upper_rows), dtype=np.int8), (upper_rows, upper_cols)), shape=(20000, 20000) ) # 提取扁平化的非零元素位置 rows_nonzero, cols_nonzero = inc_sparse.nonzero() nonzero_flat = rows_nonzero * 20000 + cols_nonzero return nonzero_flat if __name__ == "__main__": im_list = [] for filename in glob.iglob('input_file_path/*.csv', recursive=True): print(f"处理文件: {filename}") nonzero = process_csv(filename) im_list.append(nonzero) print(f"非零元素数量: {len(nonzero)}")
关键优化点解释
- 稀疏矩阵存储:
coo_matrix仅存储非零元素的行、列索引和值,对于5万行的CSV,非零元素最多5万条(上三角),内存占用仅几十KB,彻底解决内存溢出问题。 - 批量处理:用numpy数组批量处理所有映射对,替代Python逐行循环,速度提升几十到上百倍。
- 仅保留上三角:提前筛选并整理上三角索引对,避免重复存储对称位置的元素,进一步减少内存和计算量。
- 数据类型压缩:用
np.int8存储矩阵值(仅需0/1),比默认float64节省8倍内存。 - 消除冗余计算:仅在矩阵构建完成后提取非零位置,去掉原代码循环内的重复计算步骤。
额外提速建议
- 如果CSV格式固定,用
numpy.loadtxt替代pd.read_csv,读取速度更快。 - 处理数百个文件时,可使用
multiprocessing多进程并行处理,充分利用CPU多核资源。
内容的提问来源于stack exchange,提问作者Y. Pat
相关产品推荐
相关产品推荐

