如何高效判断Pandas DataFrame中是否存在匹配字典全部值的行
高效判断DataFrame中是否存在匹配字典行的方案
问题背景
在管道沿线分段点物理参数建模场景中,需要记录已完成的建模任务,以便脚本因连接问题等中断后恢复时无需从头开始。当前实现是将已完成参数存入CSV,启动时导入为DataFrame,但通过值列表匹配判断重复行的方式扩展性差(比如新增参数时需要修改值列表的构造逻辑),希望找到直接用header字典判断DataFrame中是否存在匹配行的高效方法。
优化方案
方案1:布尔索引直接匹配字典键值
直接通过字典的键值对构造DataFrame的筛选条件,判断是否存在完全匹配的行。这种方式直观,且能自动适配字典中新增的键(只要CSV列名同步更新):
import pandas as pd # 导入已完成任务记录 completed_runs_df = pd.read_csv('completed_runs.csv') for model in models: header = { 'lat': lat, 'long': long, 'press_psig': press_psig, 'diam_in': diam_in, } # 构造全列匹配条件 match_condition = True for col, val in header.items(): match_condition &= (completed_runs_df[col] == val) # 存在匹配行则跳过建模 if completed_runs_df[match_condition].any(axis=None): continue # 执行建模逻辑 # modeling goes here # 追加新任务并保存 completed_runs_df = pd.concat([completed_runs_df, pd.DataFrame([header])], ignore_index=True) completed_runs_df.to_csv('completed_runs.csv', index=False)
方案2:预存哈希集合(大数据量场景首选)
如果已完成任务量较大,每次遍历DataFrame判断会比较耗时,可以提前将已完成的行转为不可变元组存入集合,后续判断只需O(1)时间:
import pandas as pd completed_runs_df = pd.read_csv('completed_runs.csv') # 按固定键顺序将已完成行转为元组集合 header_keys = ['lat', 'long', 'press_psig', 'diam_in'] completed_set = set(tuple(row) for row in completed_runs_df[header_keys].values) for model in models: header = { 'lat': lat, 'long': long, 'press_psig': press_psig, 'diam_in': diam_in, } # 按相同顺序提取值转为元组 header_tuple = tuple(header[key] for key in header_keys) if header_tuple in completed_set: continue # 执行建模逻辑 # modeling goes here # 更新集合与CSV记录 completed_set.add(header_tuple) completed_runs_df = pd.concat([completed_runs_df, pd.DataFrame([header])], ignore_index=True) completed_runs_df.to_csv('completed_runs.csv', index=False)
方案3:isin简洁写法
利用pandas内置的isin方法一次性匹配所有键值对,代码最简洁:
import pandas as pd completed_runs_df = pd.read_csv('completed_runs.csv') for model in models: header = { 'lat': lat, 'long': long, 'press_psig': press_psig, 'diam_in': diam_in, } # 判断是否存在完全匹配的行 exists = completed_runs_df.isin(header).all(axis=1).any() if exists: continue # 执行建模逻辑 # modeling goes here completed_runs_df = pd.concat([completed_runs_df, pd.DataFrame([header])], ignore_index=True) completed_runs_df.to_csv('completed_runs.csv', index=False)
方案对比
- 方案1:逻辑直观,无需额外维护键顺序,适合参数可能新增的小数据量场景。
- 方案2:查找速度最快,适合已完成任务量较大的场景,需保证键顺序一致性。
- 方案3:代码最简洁,兼顾可读性与效率,是日常场景的折中选择。
内容的提问来源于stack exchange,提问作者Michael James
相关产品推荐
相关产品推荐

