如何高效映射scipy.sparse.lil_array?避免转为密集矩阵
高效实现布尔稀疏矩阵按列数组映射的方法
针对你提出的需求,这里提供一种直接操作稀疏矩阵内部结构的高效实现方式,完全无需转换为密集矩阵,完美适配大规模数据场景:
核心思路
利用lil_array的rows和data属性(分别存储每行的非零列索引和对应值),直接遍历每行的非零列索引,通过numpy数组索引获取对应值,同时过滤掉值为0的元素(稀疏矩阵无需存储零值),最后直接赋值到新的lil_array中。
代码实现
1. 构造示例数据
import numpy as np from scipy.sparse import lil_array # 创建布尔型lil_array示例(3×5) bool_lil = lil_array((3, 5), dtype=bool) bool_lil[0, [1, 3]] = True bool_lil[1, [0, 2, 4]] = True bool_lil[2, [1, 4]] = True # 给定的列映射数组 arr = np.array([0, -1, 0, 3, 2])
2. 高效转换实现
简洁版(列表推导式)
# 初始化结果矩阵,类型与arr一致 result_lil = lil_array(bool_lil.shape, dtype=arr.dtype) # 直接修改rows和data属性,过滤零值 result_lil.rows = [[col for col in cols if arr[col] != 0] for cols in bool_lil.rows] result_lil.data = [[arr[col] for col in cols if arr[col] != 0] for cols in bool_lil.rows]
性能优化版(numpy矢量操作)
如果矩阵规模极大,用numpy的矢量过滤会比纯Python循环更快:
result_lil = lil_array(bool_lil.shape, dtype=arr.dtype) for i in range(bool_lil.shape[0]): cols = np.array(bool_lil.rows[i]) vals = arr[cols] # 筛选非零值的索引和对应列 mask = vals != 0 result_lil.rows[i] = cols[mask].tolist() result_lil.data[i] = vals[mask].tolist()
方案优势
- 零密集转换:全程操作稀疏矩阵的内部结构,避免了密集矩阵带来的内存占用爆炸问题,适合大规模矩阵处理。
- 高效简洁:直接利用numpy的矢量索引和过滤,比纯Python循环更快,同时代码可读性强。
- 严格保留稀疏性:自动过滤掉映射后值为0的元素,符合稀疏矩阵的存储规则。
内容的提问来源于stack exchange,提问作者Umberto Fontanazza
相关产品推荐
相关产品推荐

