Python创建超大型稀疏存在/缺失矩阵,pd.crosstab内存不足如何解决
解决方案
方案1:使用Scipy稀疏矩阵(性能最优,推荐)
这种方案完全避开稠密矩阵的内存开销,适合超大规模高稀疏度的场景:
- 第一步:对人员、物品字段做整数编码
- 第二步:构造COO格式的稀疏矩阵,仅存储非0的1值
示例代码:
import pandas as pd import numpy as np from scipy.sparse import coo_matrix # 读取原始数据 df = pd.DataFrame({ "Person": ["Peter", "Peter", "Jenny", "Jenny"], "Thing": ["bike", "car", "bike", "plane"] }) # 编码为整数索引,同时保留标签映射关系 person_codes, person_labels = pd.factorize(df["Person"]) thing_codes, thing_labels = pd.factorize(df["Thing"]) # 构造稀疏矩阵,仅存非0值,dtype用int8最小化内存占用 data = np.ones(len(df), dtype=np.int8) sparse_mat = coo_matrix((data, (person_codes, thing_codes))) # 可按需转为CSR/CSC格式方便后续矩阵运算 sparse_csr = sparse_mat.tocsr()
你可以通过person_labels和thing_labels完成标签和矩阵索引的映射,比如要查Peter持有bike的状态,直接取sparse_csr[person_labels.get_loc("Peter"), thing_labels.get_loc("bike")]即可。
方案2:使用Pandas稀疏矩阵(兼容Pandas API)
如果你需要保留Pandas DataFrame的操作习惯,可以开启crosstab的稀疏模式,底层用稀疏类型存储,内存开销远低于默认的稠密DataFrame:
sparse_df = pd.crosstab(df["Person"], df["Thing"], sparse=True).astype(pd.SparseDtype("int8", 0))
返回的sparse_df是SparseDataFrame,支持普通DataFrame的绝大多数操作,同时只会存储非0的1值,0值不会占用实际内存空间。
适用场景说明
- 如果后续需要做矩阵运算、机器学习训练等场景,优先选方案1,性能和内存开销都最优
- 如果需要做表格类的筛选、分组统计等操作,选方案2更方便
- 若数据量超过单机能承载的上限,可以用Dask框架实现分布式稀疏矩阵计算,逻辑和上述方案基本一致
内容的提问来源于stack exchange,提问作者Maja
相关产品推荐
相关产品推荐

