找回密码
 立即注册
首页 业界区 安全 Python Pandas 实战:处理百万级数据关联与清洗的避坑指 ...

Python Pandas 实战:处理百万级数据关联与清洗的避坑指南

里豳朝 前天 17:15
前言

在日常的数据处理工作中,我们经常面临这样的场景:手里有一份几万行的业务 Excel 表,需要去关联另外两份几十万甚至上百万行的 CSV 数据源(比如物料主数据、历史订单表),取出对应的字段追加到原表中。
如果直接用 Excel 的 VLOOKUP 或 XLOOKUP,面对百万级数据,卡顿、崩溃几乎是常态。而使用 Python 的 pandas 库,不仅速度快,逻辑也更清晰。
本文将以一个实际的业务需求为例,记录如何使用 Pandas 高效完成多表关联(Merge)、时间戳转换以及解决最常见的“数据行数膨胀”问题。
业务场景

我们需要处理三个文件:

  • 主表 (Excel):约 2 万行,包含导入报错的订单信息。
  • 物料映射表 (CSV):约 34 万行,用于将 ITEM_CODE 转换为 OLD_PARTNUMBER。
  • 旧订单表 (CSV):约 133 万行,用于根据 订单号 + 旧物料号 获取历史订单的日期和行号信息。
目标:将文件 2 和 3 的信息匹配到文件 1 中,并导出结果。
核心技术点

在使用 Pandas 处理此类任务时,有几个关键点决定了脚本的健壮性和效率。
1. 内存优化与类型安全

读取百万行 CSV 时,如果全部读取,内存消耗巨大。同时,Excel 中的订单号可能是数字格式(如 123),而 CSV 读取出来可能是字符串("123")或者浮点数(123.0),直接关联会导致匹配失败。
最佳实践

  • 使用 usecols 只读取需要的列。
  • 使用 dtype=str 强制指定关联键为字符串,防止精度丢失或类型不匹配。
  1. # 读取百万级 CSV 的正确姿势
  2. df_orders = pd.read_csv(
  3.     'XX_ONT_SCHEDULING_T.csv',
  4.     usecols=['ORDER_NUMBER', 'OLD_PARTNUMBER', 'PROMISE_DATE'], # 只读需要的列
  5.     dtype=str, # 强制全为字符串,避免 001 变成 1,或长数字变成科学计数法
  6.     skipinitialspace=True
  7. )
  8. # 清洗空格(非常重要,CSV常带有隐形空格)
  9. df_orders['ORDER_NUMBER'] = df_orders['ORDER_NUMBER'].str.strip()
复制代码
2. 处理时间戳(向量化操作)

原始数据中包含毫秒级时间戳(如 1.70969E+12),需要转为日期格式。尽量避免使用 for 循环,利用 Pandas 的向量化操作效率更高。
  1. # 将毫秒时间戳列批量转换为日期字符串
  2. def convert_ms_to_date(ts):
  3.     try:
  4.         if pd.isna(ts) or ts == '': return None
  5.         return pd.to_datetime(ts, unit='ms').strftime('%Y-%m-%d %H:%M:%S')
  6.     except: return None
  7. # apply 应用到整列
  8. df_main['日期'] = df_main['时间戳列'].apply(convert_ms_to_date)
复制代码
3. 多键关联 (Merge/Join)

Pandas 的 merge 相当于 SQL 中的 JOIN。本例中需要基于两个字段确定唯一性。
  1. # 相当于 SQL: LEFT JOIN ON t1.order_num = t2.order_num AND t1.part = t2.part
  2. df_final = pd.merge(
  3.     df_main,
  4.     df_orders,
  5.     on=['ORDER_NUMBER', 'OLD_PARTNUMBER'], # 双键关联
  6.     how='left'
  7. )
复制代码
遇到的坑:关联后行数膨胀

这是新手最容易遇到的问题。

  • 现象:主表原有 1.7 万行,关联后变成了 2.5 万行。
  • 原因:这是一对多(1-to-N)关联导致的。参照表(CSV)中,关联键不唯一。例如同一个订单号和物料号,在历史表中可能有两条记录(比如曾经做过拆行处理)。
  • 后果:主表的一行被复制了多次,导致数据重复统计。
解决方案:在 Merge 之前,必须对右表(参照表)进行去重
  1. # 核心代码:去重
  2. # subset指定根据哪些列去重,keep='first'表示保留第一条
  3. df_orders.drop_duplicates(
  4.     subset=['ORDER_NUMBER', 'OLD_PARTNUMBER'],
  5.     keep='first',
  6.     inplace=True
  7. )
  8. # 再次关联,行数即可保持完全一致
复制代码
完整代码示例

基于 Python 3.10 的完整处理逻辑如下:
  1. import pandas as pd
  2. import os
  3. def process_data():
  4.     # 1. 读取主表
  5.     df_main = pd.read_excel('Input_File.xlsx')
  6.     original_count = len(df_main)
  7.    
  8.     # 统一关联键格式
  9.     df_main['ITEM_CODE'] = df_main['ITEM_CODE'].astype(str).str.strip()
  10.    
  11.     # 2. 读取参照表并去重 (关键步骤)
  12.     df_items = pd.read_csv('Items.csv', dtype=str, usecols=['ITEM_CODE', 'OLD_PART'])
  13.     # 确保 ITEM_CODE 唯一,否则主表会膨胀
  14.     df_items.drop_duplicates(subset=['ITEM_CODE'], keep='first', inplace=True)
  15.    
  16.     # 3. 第一次关联
  17.     df_step1 = pd.merge(df_main, df_items, on='ITEM_CODE', how='left')
  18.    
  19.     # 4. 读取历史订单表并去重
  20.     df_history = pd.read_csv('History.csv', dtype=str)
  21.     # 确保 订单号+物料号 唯一
  22.     df_history.drop_duplicates(subset=['ORDER_NUMBER', 'OLD_PART'], keep='first', inplace=True)
  23.    
  24.     # 5. 第二次关联
  25.     df_final = pd.merge(df_step1, df_history, on=['ORDER_NUMBER', 'OLD_PART'], how='left')
  26.    
  27.     # 6. 校验与输出
  28.     if len(df_final) == original_count:
  29.         print("校验通过:行数未发生变化")
  30.         df_final.to_excel('Output_Result.xlsx', index=False)
  31.     else:
  32.         print(f"警告:行数发生改变 (原: {original_count} -> 现: {len(df_final)})")
  33. if __name__ == '__main__':
  34.     process_data()
复制代码
总结

Pandas 在处理中等规模数据(百万行级别)时,是 Excel 最好的替代品。在写脚本时,只要注意以下三点,就能避开 90% 的坑:

  • 类型对齐:关联键统一转为 str 再 Merge。
  • 去重处理:在 left join 之前,务必确保右表的关联键是唯一的(drop_duplicates)。
  • 按需读取:大文件只读需要的列,节省内存。
希望这篇文章能对大家处理数据有所帮助。
作者:飞鸿影
出处:http://52fhy.cnblogs.com/
版权申明:没有标明转载或特殊申明均为作者原创。本文采用以下协议进行授权,自由转载 - 非商用 - 非衍生 - 保持署名 | Creative Commons BY-NC-ND 3.0,转载请注明作者及出处。
1.png

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册