如何从字典直接创建以0为缺失值的Pandas稀疏DataFrame(不生成密集版)
如何直接创建以0为缺失值的稀疏DataFrame(避免生成密集矩阵)
要在不生成密集矩阵的前提下,直接构建以0为填充值的稀疏DataFrame,核心是让pandas在数据对齐阶段就用稀疏类型的填充值0替代NaN,而非事后转换。以下是几种可行方案:
方案1:将每条记录转为稀疏Series后拼接
先把字典中的每个子记录转换为指定填充值的稀疏Series,再横向拼接后转置,全程保持稀疏结构:
import pandas as pd import numpy as np record = { 0: {"item1": 1, "item2": 3}, 1: {"item1": 2, "item3": 1, "item4": 50}, } # 遍历记录,生成稀疏Series字典后构建DataFrame dfs = pd.DataFrame({ idx: pd.Series(data, dtype=pd.SparseDtype("int", 0)) for idx, data in record.items() }).T
验证结果:
item1 item2 item3 item4 0 1 3 0 0 1 2 0 1 50
检查稀疏密度:
print(dfs.sparse.density) # 输出 0.625
方案2:用pd.concat拼接稀疏Series列表
和方案1原理一致,改用列表推导生成稀疏Series后纵向拼接再转置:
sparse_series_list = [ pd.Series(data, dtype=pd.SparseDtype("int", 0), name=idx) for idx, data in record.items() ] dfs = pd.concat(sparse_series_list, axis=1).T
方案3:基于SparseArray逐行构建
先收集所有列名,再为每行生成稀疏数组,直接构建DataFrame:
# 收集所有唯一列名并排序 all_columns = sorted({key for sub_dict in record.values() for key in sub_dict.keys()}) # 为每行生成稀疏数组 sparse_rows = [] for data in record.values(): row_values = [data.get(col, 0) for col in all_columns] sparse_rows.append(pd.SparseArray(row_values, dtype=pd.SparseDtype("int", 0))) # 构建稀疏DataFrame dfs = pd.DataFrame(sparse_rows, columns=all_columns, index=record.keys())
为什么原代码无法生效?
当使用pd.DataFrame.from_dict(record, orient="index", dtype=pd.SparseDtype("int", 0))时,pandas会先对齐所有列,缺失值填充NaN。但稀疏类型SparseDtype("int", 0)的填充值是0,NaN不属于该类型的有效值,因此pandas会自动将列类型提升为可空浮点数(混合int和NaN),最终无法形成稀疏列结构,也就无法使用.sparse访问器。
而上述方案在创建稀疏Series/数组时,直接将缺失的元素映射为填充值0,数据对齐阶段全程保持稀疏结构,不会生成中间密集矩阵,完美适配极稀疏数据场景。
内容的提问来源于stack exchange,提问作者speedboat_work
相关产品推荐
相关产品推荐

