如何在指定chunksize的Pandas DataFrame中移除跨块重复行?
分块读取CSV时跨块去重的解决方案
当处理大型CSV文件采用分块读取的方式时,要彻底移除所有重复行(包括不同分块中的重复项),核心是要跟踪已经出现过的行,后续分块遇到重复项直接过滤。
实现思路
- 用集合存储已出现的行的唯一标识(比如行转成元组),集合的查询效率为O(1),适合高频判断
- 遍历每个分块:先过滤掉已出现的行,再将当前分块的新行记录到集合中
- 可选择将去重后的分块合并为DataFrame,或直接写入新文件(超大文件优先选后者,避免内存溢出)
代码实现
import pandas as pd # 初始化集合存储已出现的行(元组格式,可哈希) seen_rows = set() # 存储去重后的分块(超大文件建议直接写入新文件,无需此列表) deduplicated_chunks = [] # 分块读取原CSV文件 for chunk in pd.read_csv("tmp.csv", sep="|", chunksize=3): # 将当前分块的每行转为元组,用于判断重复 chunk_rows = [tuple(row) for row in chunk.itertuples(index=False, name=None)] # 生成过滤掩码:仅保留未出现过的行 keep_mask = [row not in seen_rows for row in chunk_rows] # 过滤当前分块 filtered_chunk = chunk[keep_mask] # 将新增的行加入已见集合 seen_rows.update([row for row, keep in zip(chunk_rows, keep_mask) if keep]) # 保存过滤后的分块(超大文件替换为:filtered_chunk.to_csv("deduplicated.csv", mode='a', header=False, sep="|")) deduplicated_chunks.append(filtered_chunk) # 合并所有去重后的分块(超大文件跳过此步骤) final_deduplicated_df = pd.concat(deduplicated_chunks, ignore_index=True) print(final_deduplicated_df)
关键细节说明
- 行的唯一标识:用元组存储行数据是因为元组可哈希,能存入集合;也可以用
hash(tuple(row))存储哈希值,进一步减少内存占用,哈希碰撞概率极低,普通场景可忽略 - 内存优化方案:如果处理的是超大型文件,不要将分块存入列表,而是在遍历过程中直接用
to_csv的mode='a'参数追加写入新文件,全程仅占用单个分块的内存 - 验证结果:原示例CSV中
(1,1)出现4次,去重后仅保留首次出现的行,最终输出的DataFrame为:
A B 0 1 1 1 2 1 2 1 2 3 1 3
内容的提问来源于stack exchange,提问作者Márcio Mocellin
相关产品推荐
相关产品推荐

