在数据处理场景中,我们经常会遇到需要把CSV文件中已经处理过的行提取出来保存到新文件,同时把这些行从原文件中删除的需求,比如批量处理用户数据后,把已处理的数据归档,避免下次重复处理。下面介绍两种常用的实现方式。

方案一:使用原生Python csv模块实现
原生csv模块不需要额外安装依赖,适合轻量级的CSV处理场景,核心思路是先读取原文件的所有行,区分出需要保留的行和需要迁移的行,分别写入新文件和覆盖原文件。
实现步骤
- 读取原CSV文件的所有行内容
- 根据处理标记筛选需要迁移的行和需要保留的行
- 将需要迁移的行写入新的CSV文件
- 将需要保留的行写回原CSV文件,完成移除操作
示例代码
假设原CSV文件有is_processed字段,值为1表示该行已经处理完成,需要迁移:
import csv
# 原文件路径和新文件路径
source_file = "source.csv"
target_file = "processed.csv"
# 存储需要保留的行和需要迁移的行
rows_to_keep = []
rows_to_move = []
# 读取原文件内容
with open(source_file, "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
# 获取表头
headers = reader.fieldnames
for row in reader:
# 判断该行是否已经处理,假设is_processed字段为1表示已处理
if row.get("is_processed") == "1":
rows_to_move.append(row)
else:
rows_to_keep.append(row)
# 将已处理的行写入新文件
with open(target_file, "w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=headers)
writer.writeheader()
writer.writerows(rows_to_move)
# 将未处理的行写回原文件,完成移除操作
with open(source_file, "w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=headers)
writer.writeheader()
writer.writerows(rows_to_keep)
print("CSV行迁移和移除操作完成")
方案二:使用pandas库实现
pandas是Python中常用的数据处理库,处理CSV文件更加简洁高效,适合数据量较大或者需要复杂筛选逻辑的场景,需要先通过pip install pandas安装依赖。
实现步骤
- 使用pandas读取原CSV文件为DataFrame
- 通过条件筛选得到已处理行和未处理行两个DataFrame
- 将已处理行保存到新CSV文件
- 将未处理行保存回原CSV文件,覆盖原有内容
示例代码
同样基于is_processed字段判断已处理行:
import pandas as pd
# 原文件路径和新文件路径
source_file = "source.csv"
target_file = "processed.csv"
# 读取原CSV文件
df = pd.read_csv(source_file, encoding="utf-8")
# 筛选已处理的行和未处理的行
processed_df = df[df["is_processed"] == 1]
remaining_df = df[df["is_processed"] != 1]
# 将已处理的行写入新文件
processed_df.to_csv(target_file, index=False, encoding="utf-8")
# 将未处理的行写回原文件,完成移除操作
remaining_df.to_csv(source_file, index=False, encoding="utf-8")
print("CSV行迁移和移除操作完成")
操作注意事项
- 操作前建议先备份原CSV文件,避免误操作导致数据丢失
- 读取和写入文件时注意编码设置,中文内容建议使用utf-8编码
- 如果CSV文件没有明确的处理标记字段,可以根据行内容、行索引等自定义筛选逻辑
- 处理大文件时,原生csv模块的内存占用更低,pandas更适合需要复杂数据处理的场景
如果原文件路径是192.168.0.1/data/source.csv,新文件路径是192.168.0.1/data/processed.csv,只需要替换代码中的文件路径即可,不需要修改其他逻辑。