You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

处理两个大型Pandas DataFrame去重效率低下,求更优解决方案

高效移除大DataFrame中重复phone行的优化方案

你当前的嵌套循环方案时间复杂度是O(M*N)(650万 × 10万 = 6.5e12次操作),属于低效的暴力匹配,必然耗时极长。以下是几种远优于嵌套循环的解决方案,覆盖Pandas、NumPy、数据库等多种场景:

一、Pandas内置向量化方法(最简洁高效)

利用Pandas的isin()方法结合集合查询,集合的成员查询是O(1)时间复杂度,整体时间复杂度降到O(M+N):

dfll = df.loc[df['Cell'] == 'N'].copy().reset_index(drop=True)
wdnc = pd.read_fwf(path, names=['phone'])

# 将wdnc的phone转为集合,大幅提升查询效率
excluded_phones = set(wdnc['phone'])
# 筛选出phone不在排除列表中的行
dfll_filtered = dfll[~dfll['phone'].isin(excluded_phones)]
# 统计移除数量
removed_count = len(dfll) - len(dfll_filtered)
print(f'Cases removed: {removed_count}')

如果担心内存占用,也可以直接传入wdnc['phone']到isin()中,Pandas内部会做优化,但转集合对超大样本的查询速度提升更明显。

二、NumPy向量化操作(性能接近Pandas,适合纯数值场景)

NumPy的in1d()函数底层基于C实现,能快速生成匹配掩码,速度极快:

import numpy as np

dfll = df.loc[df['Cell'] == 'N'].copy().reset_index(drop=True)
wdnc = pd.read_fwf(path, names=['phone'])

# 转为NumPy数组
wdnc_arr = wdnc['phone'].to_numpy()
dfll_arr = dfll['phone'].to_numpy()

# 生成掩码:标记phone不在wdnc中的行
mask = ~np.in1d(dfll_arr, wdnc_arr)
dfll_filtered = dfll[mask]
removed_count = len(dfll) - len(dfll_filtered)
print(f'Cases removed: {removed_count}')

三、数据库工具(适合内存不足以加载全量数据的场景)

如果650万行的wdnc占用内存过高,可以用SQLite临时数据库,利用数据库的索引优化查询:

import sqlite3
import pandas as pd

dfll = df.loc[df['Cell'] == 'N'].copy().reset_index(drop=True)
chunk_size = 100000

# 创建内存中的SQLite数据库
conn = sqlite3.connect(':memory:')
# 导入dfll到临时表
dfll.to_sql('dfll_table', conn, index=False)

# 分块导入wdnc到临时表,避免一次性加载内存
for chunk in pd.read_fwf(path, names=['phone'], chunksize=chunk_size):
    chunk.to_sql('wdnc_table', conn, index=False, if_exists='append')

# 创建索引加速查询
conn.execute('CREATE INDEX idx_phone ON wdnc_table(phone);')

# 执行筛选查询
query = """
SELECT * FROM dfll_table
WHERE phone NOT IN (SELECT phone FROM wdnc_table)
"""
dfll_filtered = pd.read_sql(query, conn)
removed_count = len(dfll) - len(dfll_filtered)
print(f'Cases removed: {removed_count}')

conn.close()

四、分块处理(极端内存不足时的备选方案)

如果连集合都无法完全加载到内存,可以分块读取wdnc,逐步累积排除的phone集合:

dfll = df.loc[df['Cell'] == 'N'].copy().reset_index(drop=True)
chunk_size = 50000
excluded_phones = set()

# 分块读取wdnc,逐步添加到排除集合
for chunk in pd.read_fwf(path, names=['phone'], chunksize=chunk_size):
    excluded_phones.update(chunk['phone'].tolist())

# 最终筛选
dfll_filtered = dfll[~dfll['phone'].isin(excluded_phones)]
removed_count = len(dfll) - len(dfll_filtered)
print(f'Cases removed: {removed_count}')

这些方案的核心思路都是避免暴力循环,利用哈希查询、向量化操作或数据库索引将时间复杂度从O(M*N)降到O(M+N),性能提升几个数量级。

内容的提问来源于stack exchange,提问作者MotoMatt5040

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:24:22