Python中如何高效为DataFrame同一行不同列批量赋值
高效实现方案
禁止逐行迭代修改/追加pandas DataFrame,这类操作会触发全量内存拷贝,性能极差。最优方案是先把所有原始数据解析成结构化的字典列表,一次性构造DataFrame;后续批量追加也用同样思路攒够数据再一次性合并,性能比逐行迭代高2~3个数量级。
单字典转行实现
import pandas as pd import re # 示例输入字典 test = {'AAGUFU 60 (MDE).jpg': 0.2825904813711154, 'AAGUFU 60 (MCE).jpg': 0.27073007232248, 'AAGUFU 60 (MCA).jpg': 0.3736480594737323, 'AAGUFU 60 (MCP).jpg': 0.45155877307246917} # 初始化空DataFrame df = pd.DataFrame(columns = ["specimen", "MDE", "MCE", "MCA", "MCP"]) def parse_single_dict(input_dict): """解析单个字典为符合DF结构的行字典""" row = {col: None for col in df.columns} for filename, val in input_dict.items(): # 单次正则匹配同时提取样本名和括号内缩写 match_res = re.match(r'(.+?) \(([A-Z]+)\)\.jpg', filename) specimen, abbr = match_res.group(1), match_res.group(2) row["specimen"] = specimen row[abbr] = val return row # 解析单字典后合并到DF,ignore_index重置索引避免冲突 single_row = parse_single_dict(test) df = pd.concat([df, pd.DataFrame([single_row])], ignore_index=True) # 如需保留3位小数,统一做round即可 df = df.round(3)
运行后得到的DF结构与预期完全一致:
| specimen | MDE | MCE | MCA | MCP |
|---|---|---|---|---|
| AAGUFU 60 | 0.283 | 0.271 | 0.374 | 0.452 |
多字典批量追加场景
如果后续需要处理多组同类字典,不要每处理一个字典就执行一次concat,先把所有字典解析为行存入列表,最后一次性生成DataFrame,性能最优:
# 所有待处理的同类字典统一放入列表 all_dict_list = [test_dict1, test_dict2, test_dict3] # 批量解析所有字典 all_rows = [parse_single_dict(d) for d in all_dict_list] # 一次性生成最终DF,无需提前初始化空DF final_df = pd.DataFrame(all_rows, columns=["specimen", "MDE", "MCE", "MCA", "MCP"]).round(3)
原有代码问题排查
- 逻辑错误:三层嵌套循环完全冗余,遍历
test.values()时会把所有测量值重复赋值给当前列,最终值会被最后一次遍历的结果覆盖;且空DataFrame用iterrows()遍历不会返回任何行,赋值逻辑根本不会触发。 - 性能缺陷:
iterrows()返回的是行数据的副本而非原数据视图,本身就不支持稳定的原地修改;逐行追加/修改的时间复杂度为O(n²),数据量超过千条就会出现明显卡顿。 - 写法冗余:提取文件名信息不需要混用正则和字符串切片,单次正则分组即可同时拿到样本名和缩写,代码更易维护。
补充提示:如果存在同一样本分散在不同字典的情况,解析完成后可以用
df.groupby('specimen', as_index=False).first()做聚合,避免出现重复行。
内容的提问来源于stack exchange,提问作者Davi Lee Bang
相关产品推荐
相关产品推荐

