Pandas:基于其他DataFrame更新列的大数据量警告问题与优化建议
优化租车公司车辆数据更新代码(解决SettingWithCopyWarning及大数据量问题)
首先,咱们先搞清楚原代码触发警告的核心原因:你用df_cars[['RefNo', 'Driver']].set_index('RefNo')这种切片方式时,pandas返回的可能是原DataFrame的视图而非独立副本,后续的update操作就会触发SettingWithCopy警告——小数据量下可能没实质影响,但大数据量下不仅警告烦人,还可能导致数据更新异常。
下面是针对你的需求重新设计的优化方案,既解决警告问题,又提升大数据量下的处理效率:
第一步:预处理出库入库数据,提取每个车辆的最新状态变更记录
原代码的合并、日期转换逻辑没问题,但用groupby取最新记录比sort+drop_duplicates更高效,尤其适合25-30k级别的数据:
import pandas as pd # 合并出库和入库记录 df_out_in = pd.concat([df_out, df_in]) # 统一转换为datetime格式(如果原始数据格式固定,可加format参数提速) df_out_in['Date'] = pd.to_datetime(df_out_in['Date']) # 按车辆RefNo分组,直接取每个组的最后一条(最新日期)记录 latest_updates = df_out_in.sort_values('Date').groupby('RefNo').last().reset_index()
第二步:用左连接+combine_first安全更新df_cars
放弃原代码中容易触发视图问题的update方式,改用merge+combine_first,全程操作副本,彻底避免警告:
# 左连接df_cars和最新更新记录,保留原表所有车辆 df_cars_updated = df_cars.merge( latest_updates[['RefNo', 'Driver', 'Date']], # 只取需要更新的列 on='RefNo', how='left', suffixes=('', '_latest') # 区分原列和新列 ) # 更新Driver列:优先用最新记录的驾驶员,原空值保留 df_cars_updated['Driver'] = df_cars_updated['Driver_latest'].combine_first(df_cars_updated['Driver']) # 更新Date列:优先用最新状态变更日期,无记录的显示NaT df_cars_updated['Date'] = df_cars_updated['Date_latest'].combine_first(df_cars_updated['Date']) # 清理临时列,确保日期格式统一 df_cars_updated = df_cars_updated.drop(columns=['Driver_latest', 'Date_latest']) df_cars_updated['Date'] = pd.to_datetime(df_cars_updated['Date'])
为什么这个方案更好?
- 彻底解决警告:所有操作都基于新创建的DataFrame副本,完全避开视图/副本的混淆问题
- 大数据量更高效:
groupby('RefNo').last()的底层实现比drop_duplicates更适合大规模数据,处理速度更快 - 逻辑更清晰:通过显式的左连接和
combine_first,你能一眼看明白更新规则,后续维护更方便
运行这段代码后,你会得到和预期完全一致的df_cars_updated,而且大数据量下不会再出现警告。
额外优化建议(针对大数据量)
- 提前设置
RefNo为索引:如果后续经常按车辆编号操作,把df_cars和df_out_in的RefNo设为索引,能大幅提升合并效率 - 指定列类型:读取原始数据时,用
dtype参数指定RefNo为字符串、Brand/Model为category类型,减少内存占用 - 日期转换提速:如果你的日期格式固定(比如
YYYY-M-D),在pd.to_datetime里加上format='%Y-%m-%d',能加快转换速度
内容的提问来源于stack exchange,提问作者Nikos P
相关产品推荐
相关产品推荐

