
本文介绍如何将 Pandas DataFrame 中的三元组(行标识、列标识、数值)高效转换为带可追溯标签的 SciPy 稀疏矩阵,并支持如 m.T.dot(m) 等线性代数运算,同时保留分支号、商品编码等业务语义标签。
本文介绍如何将 pandas dataframe 中的三元组(行标识、列标识、数值)高效转换为带可追溯标签的 scipy 稀疏矩阵,并支持如 `m.t.dot(m)` 等线性代数运算,同时保留分支号、商品编码等业务语义标签。
在处理高维但高度稀疏的交叉表数据(例如:463 个门店 × 5235 种商品的销售价格)时,使用稠密 NumPy 数组会浪费大量内存(约 463×5235×8 ≈ 193 MB),而 SciPy 的 csr_matrix 能将存储压缩至非空值数量级(本例仅约 44.8 万条记录)。但原生 SciPy 稀疏矩阵不支持行列标签——这正是业务分析中不可或缺的语义信息。
推荐采用 pd.factorize() 替代手动字典映射,它能原子性地生成整数索引与唯一标签,避免排序/重复问题,且性能更优:
import pandas as pd
import scipy.sparse as sp
def build_labeled_sparse_matrix(
df,
row_col: str,
col_col: str,
value_col: str
) -> tuple[sp.csr_matrix, pd.Index, pd.Index]:
"""
构建带行列标签的 CSR 稀疏矩阵
Returns:
m: csr_matrix,形状为 (n_rows, n_cols)
row_labels: pd.Index,对应行标签(如 BranchNumber)
col_labels: pd.Index,对应列标签(如 ModelArticleNumber)
"""
rows, row_labels = pd.factorize(df[row_col])
cols, col_labels = pd.factorize(df[col_col])
# 显式指定 shape,确保矩阵维度与唯一标签数一致
m = sp.csr_matrix(
(df[value_col], (rows, cols)),
shape=(len(row_labels), len(col_labels))
)
return m, pd.Index(row_labels), pd.Index(col_labels)
# 使用示例
m, branches, models = build_labeled_sparse_matrix(
df, 'BranchNumber', 'ModelArticleNumber', 'ActualSellingPrice'
)
print(f"稀疏矩阵形状: {m.shape}, 密度: {m.nnz / m.size:.6f}")
print(f"行标签示例: {branches[:3].tolist()}") # [101, 102, 103]
print(f"列标签示例: {models[:3].tolist()}") # ['A001', 'A002', 'A003']
✅ 关键优势:
-
m.T.dot(m)可直接高效执行(时间复杂度 O(nnz × avg_degree)),用于计算商品共现矩阵或协同过滤相似度; - 通过
branches[10]和models[20]即可精准定位m[10, 20]对应的业务实体; -
pd.factorize()自动处理缺失值(默认编码为-1,需提前清洗)和类型一致性(如object列自动哈希)。
⚠️ 注意事项:
- 输入 DataFrame 必须无缺失值(
NaN)于row_col/col_col,否则factorize会将NaN视为有效类别并分配索引-1,导致矩阵索引错位;建议预处理:df = df.dropna(subset=[row_col, col_col]); - 若需频繁按标签查询(如“获取所有门店对商品 A001 的售价”),可进一步封装为
SparseMatrixFrame类,内置.loc风格索引器; - 内存敏感场景下,避免转为稠密矩阵(
m.toarray()),其会瞬间引爆内存。
进阶选择:若需 DataFrame 接口(如 .groupby()、.describe()),可用 pd.DataFrame.sparse.from_spmatrix() 构建带标签的稀疏 DataFrame:
df_sparse = pd.DataFrame.sparse.from_spmatrix(
m, index=branches, columns=models
)
# 此时 df_sparse.iloc[0, 0] 返回 SparseArray,支持 .sparse.density 等属性
该方案兼顾了 SciPy 的计算效率与 Pandas 的语义可读性,是构建推荐系统、市场篮子分析或图邻接矩阵的理想起点。










