替代iteruples()优化JSON转DataFrame入库前处理性能
优化方案:提升JSON转DataFrame的处理效率
你的核心问题在于逐行循环+df.at单元素赋值的组合,这在大数据量下会产生极大的性能开销——df.at每次操作都会触发DataFrame的内部状态更新,而Python层面的循环本身就比pandas的向量化操作慢很多。以下是针对性的优化方案:
核心优化思路
- 避免逐元素修改DataFrame,改用批量生成数据后一次性赋值
- 用字典映射替代match语句,简化逻辑同时提升效率
- 尽量利用pandas的内置方法或纯Python列表操作,减少DataFrame的频繁修改
方案一:apply+结构化映射(简洁高效)
通过apply将h_batb列的嵌套列表转换为结构化的Series,再合并回原DataFrame:
import pandas as pd def process_ladders(ladder_list): # 初始化所有目标列的默认值 output = { 'b_0_pos': None, 'b_0_price': None, 'b_0_dep': None, 'b_1_pos': None, 'b_1_price': None, 'b_1_dep': None, 'b_2_pos': None, 'b_2_price': None, 'b_2_dep': None } for ladder in ladder_list: pos = ladder[0] # 只处理0/1/2的情况,其他忽略 if pos in (0, 1, 2): prefix = f'b_{pos}_' output[f'{prefix}pos'] = ladder[0] output[f'{prefix}price'] = ladder[1] output[f'{prefix}dep'] = ladder[2] return pd.Series(output) # 生成结构化的扩展列并合并到原DataFrame expanded_cols = df_batb['h_batb'].apply(process_ladders) df_batb = pd.concat([df_batb, expanded_cols], axis=1)
优势
- 代码简洁易维护,利用pandas优化过的
apply逻辑,比手动循环+df.at快数倍 - 一次性生成所有目标列,避免多次修改原DataFrame的开销
方案二:纯列表预处理(极致性能)
如果数据量特别大,apply的性能仍不够,可以用纯Python列表收集所有数据后批量赋值——列表的append操作开销远低于DataFrame的单元素修改:
# 初始化用于存储结果的列表 b0_pos, b0_price, b0_dep = [], [], [] b1_pos, b1_price, b1_dep = [], [], [] b2_pos, b2_price, b2_dep = [], [], [] for ladder_list in df_batb['h_batb']: # 默认值设为None,可根据需求改为NaN或其他值 res0 = [None, None, None] res1 = [None, None, None] res2 = [None, None, None] for ladder in ladder_list: pos = ladder[0] if pos == 0: res0 = ladder elif pos == 1: res1 = ladder elif pos == 2: res2 = ladder # 将当前行的结果追加到对应列表 b0_pos.append(res0[0]) b0_price.append(res0[1]) b0_dep.append(res0[2]) b1_pos.append(res1[0]) b1_price.append(res1[1]) b1_dep.append(res1[2]) b2_pos.append(res2[0]) b2_price.append(res2[1]) b2_dep.append(res2[2]) # 批量赋值给原DataFrame的列 df_batb['b_0_pos'] = b0_pos df_batb['b_0_price'] = b0_price df_batb['b_0_dep'] = b0_dep df_batb['b_1_pos'] = b1_pos df_batb['b_1_price'] = b1_price df_batb['b_1_dep'] = b1_dep df_batb['b_2_pos'] = b2_pos df_batb['b_2_price'] = b2_price df_batb['b_2_dep'] = b2_dep
优势
- 完全避免了DataFrame的逐元素修改操作,性能提升最明显
- 纯Python循环逻辑简单,适合超大规模数据集
关键优化点总结
- 抛弃
df.at:单元素赋值的开销在大数据量下会被无限放大,改用批量赋值 - 减少循环内的分支复杂度:用简单条件判断替代match语句,降低逻辑开销
- 优先批量操作:pandas的核心优势是向量化/批量处理,尽量避免手动逐行操作
内容的提问来源于stack exchange,提问作者Barry Gibson
相关产品推荐
相关产品推荐

