如何快速将Pandas数据框中的索引列表加载到稀疏矩阵?
快速构建百万级布尔稀疏矩阵的优化方案
嘿,这个场景我太有体会了——用Python循环遍历百万级数据来逐个赋值稀疏矩阵,确实会慢到让人抓狂。咱们换个思路,用向量化操作+稀疏矩阵原生构造方法,能把耗时从几分钟压缩到几秒!
核心思路:用COO矩阵直接从坐标对构造
scipy.sparse里的coo_matrix是专门为从「行索引/列索引对」构造稀疏矩阵设计的,底层是C实现的向量化操作,比Python循环高效几个数量级。具体步骤是:
- 把每一行的索引,重复对应列表长度的次数(比如第0行有3个元素,就生成3个0作为行索引)
- 把所有列表里的元素扁平化,得到所有要设为
True的列索引 - 用这两个索引数组直接构造COO矩阵,再转成你需要的LIL格式(如果需要的话)
具体代码实现
import pandas as pd import numpy as np from scipy.sparse import coo_matrix, lil_matrix # 你的原始数据(示例) df = pd.DataFrame({'lists': [[0, 1, 2], [6, 7, 8], [3, 4, 5]]}) n_rows = len(df) n_cols = 30000 # 你的实际总列数 # 1. 生成重复的行索引:每个行号重复对应list的长度次 row_indices = np.repeat(df.index, df['lists'].str.len()) # 2. 扁平化所有列索引:把所有list里的元素拼成一个一维数组 col_indices = np.concatenate(df['lists'].tolist()) # 3. 构造COO矩阵,再转成LIL格式(如果后续需要修改矩阵的话) # 这里用bool类型的全1数组作为值,因为我们要设为True sparse_matrix = coo_matrix( (np.ones(len(row_indices), dtype=bool), (row_indices, col_indices)), shape=(n_rows, n_cols) ).tolil()
额外优化技巧
- 如果不需要LIL格式,直接用COO/CSR矩阵:LIL矩阵适合随机修改,但存储和运算效率不如COO或CSR。如果你的后续操作只是读取、矩阵乘法等,直接用
coo_matrix转csr_matrix会更高效。 - 去重列索引:如果你的
lists列里有重复的数字(比如某行的列表里出现同一个列号多次),可以先去重减少索引数组的长度:
虽然布尔值重复赋值不影响结果,但去重后能减少内存占用和构造时间。df['lists'] = df['lists'].apply(lambda x: list(set(x))) - 避免用tolist():如果你的
lists列已经是numpy数组格式,直接用np.concatenate(df['lists'].values)会比tolist()更快,不过Pandas的str.len()处理列表列也很高效。
这个方法处理150万行的数据,全程应该在10秒以内就能完成,绝对比循环快太多!
内容的提问来源于stack exchange,提问作者Paul ten Kaate
相关产品推荐
相关产品推荐

