如何高效将十万级Pandas DataFrame转换为指定嵌套字典(避免逐行迭代)
高效转换Pandas DataFrame为嵌套字典的方案
针对10万行量级的DataFrame,要避免逐行迭代,利用Pandas的层级索引+分组转换可以实现高效的嵌套字典生成,完全匹配你需要的结构。以下是具体实现步骤:
1. 转换数据类型(关键前提)
你的示例数据中所有字段都是字符串类型,但目标字典里是数值类型,第一步先做类型转换,否则最终字典的键和值会是字符串,不符合预期:
import pandas as pd # 加载示例数据(原始数据直接复用即可) df = pd.DataFrame({'cluster': ['5', '5', '5', '5', '5', '5'], 'mdse_item_i': ['23627102', '23627102', '23627102', '23627102', '23627102', '23627102'], 'predPriceQty': ['35.675543', '33.236678', '35.675543', '35.675543', '35.675543', '35.675543'], 'schedule_i': ['56', '56', '56', '56', '56', '56'], 'segment_id': ['4123', '4123', '4144', '4161', '4295', '4454'], 'wk': ['1', '2', '1', '1', '1', '1']} ) # 转换为目标数据类型 df['segment_id'] = df['segment_id'].astype(int) df['cluster'] = df['cluster'].astype(int) df['schedule_i'] = df['schedule_i'].astype(float) # 匹配示例中的56.0格式,若要整数可改astype(int) df['mdse_item_i'] = df['mdse_item_i'].astype(float) df['wk'] = df['wk'].astype(int) df['predPriceQty'] = df['predPriceQty'].astype(float)
2. 构建层级索引的Series
将需要作为嵌套层级的字段设置为多层索引,把predPriceQty作为Series的值,利用Pandas的层级操作快速分组:
# 设置多层索引,顺序对应嵌套层级:外层(segment_id, cluster) → schedule_i → mdse_item_i → wk s = df.set_index(['segment_id', 'cluster', 'schedule_i', 'mdse_item_i', 'wk'])['predPriceQty']
3. 层级转换为嵌套字典
通过分组+递归转换的方式,将多层索引的Series转换成目标嵌套结构。这种方式完全基于Pandas的向量化操作,避免逐行循环,效率提升显著:
def build_nested_dict(sub_series): # 递归处理层级:从schedule_i开始,逐层嵌套到wk if sub_series.index.nlevels == 3: return {k: build_nested_dict(sub_series.xs(k, level=0)) for k in sub_series.index.unique(level=0)} elif sub_series.index.nlevels == 2: return {k: sub_series.xs(k, level=0).to_dict() for k in sub_series.index.unique(level=0)} elif sub_series.index.nlevels == 1: return sub_series.to_dict() # 按最外层的(segment_id, cluster)元组分列,生成最终字典 result = {} for (seg_id, clust), sub_s in s.groupby(level=['segment_id', 'cluster']): # 去掉前两层索引,剩下schedule_i、mdse_item_i、wk stripped_s = sub_s.droplevel(['segment_id', 'cluster']) result[(seg_id, clust)] = build_nested_dict(stripped_s)
验证输出结构
运行后,result的结构完全匹配你的需求:
print(result) # 输出: # {(4123, 5): {56.0: {23627102.0: {1: 35.675543, 2: 33.236678}}}, # (4144, 5): {56.0: {23627102.0: {1: 35.675543}}}, # (4161, 5): {56.0: {23627102.0: {1: 35.675543}}}, # (4295, 5): {56.0: {23627102.0: {1: 35.675543}}}, # (4454, 5): {56.0: {23627102.0: {1: 35.675543}}}}
效率说明
这种方法的核心是利用Pandas内部优化的向量化分组和索引操作,避免了Python层面的逐行循环(比如iterrows()或字典推导式遍历所有行),对于10万行数据,处理速度会比逐行迭代快一个数量级以上,完全适配你的数据规模。
内容的提问来源于stack exchange,提问作者Vivek
相关产品推荐
相关产品推荐

