基于层级优先级条件去重的Pandas与SQLite实现方法
按指定优先级去重的实现方案
优先提供Pandas向量化实现方案,内存允许的情况下处理千万级以内数据性能足够;如果数据体量过大不适合加载到内存,可直接使用SQLite端执行的方案。
方案1:Python Pandas 高效实现
核心思路
全程使用Pandas内置向量化操作,无逐行遍历开销,大表处理速度远快于自定义循环逻辑:
- 从
Category字段提取优先级数字,生成临时排序权重,数字越小优先级越高 - 按权重升序排序,保证同
Text分组下优先级最高的记录排在组内最前 - 按
Text字段去重时保留组内第一条记录,即为每组优先级最高的目标行 - 处理完成后删除临时权重列即可
实现代码
import pandas as pd # 原始数据加载,实际使用时替换为对应读取逻辑,比如pd.read_sql、pd.read_csv df = pd.DataFrame( [ (1, "text", "Priority 3"), (2, "text", "Priority 1"), (3, "text", "Priority 2"), (4, "text 2", "Priority 3"), (5, "text 2", "Priority 2") ], columns=["ID", "Text", "Category"] ) # 核心去重逻辑 # 提取优先级数字生成临时排序列 df["_priority_rank"] = df["Category"].str.extract(r"(\d+)").astype(int) # 按优先级升序排列 df = df.sort_values(by="_priority_rank", ascending=True, ignore_index=True) # 按Text分组保留第一条最高优先级记录,删除临时列 result = df.drop_duplicates(subset=["Text"], keep="first").drop(columns=["_priority_rank"])
运行后result输出与预期完全一致:
| ID | Text | Category |
|---|---|---|
| 2 | text | Priority 1 |
| 5 | text 2 | Priority 2 |
如果你的优先级规则是无规律自定义文本,可替换临时列生成逻辑为显式映射,例如:
priority_map = {"Priority 1": 1, "Priority 2": 2, "Priority 3": 3} df["_priority_rank"] = df["Category"].map(priority_map)
方案2:SQLite 实现
如果数据存储在SQLite中且体量过大无法加载到内存,可直接在库内执行去重逻辑,3.25及以上版本SQLite支持窗口函数,执行效率很高。
核心思路
通过窗口函数给同Text分组下的记录按优先级从高到低打行号,筛选行号为1的记录即为需要保留的结果。
实现代码
-- 仅查询去重后的结果,不修改原表 SELECT ID, Text, Category FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY Text ORDER BY CAST(REPLACE(Category, 'Priority ', '') AS INTEGER) ASC ) AS row_rank FROM your_target_table ) WHERE row_rank = 1; -- 直接删除原表中不符合保留规则的重复数据 DELETE FROM your_target_table WHERE ID NOT IN ( SELECT ID FROM ( SELECT ID, ROW_NUMBER() OVER ( PARTITION BY Text ORDER BY CAST(REPLACE(Category, 'Priority ', '') AS INTEGER) ASC ) AS row_rank FROM your_target_table ) WHERE row_rank = 1 );
如果使用的SQLite版本低于3.25不支持窗口函数,可使用关联子查询实现相同逻辑:
SELECT t1.ID, t1.Text, t1.Category FROM your_target_table t1 WHERE NOT EXISTS ( SELECT 1 FROM your_target_table t2 WHERE t2.Text = t1.Text AND CAST(REPLACE(t2.Category, 'Priority ', '') AS INTEGER) < CAST(REPLACE(t1.Category, 'Priority ', '') AS INTEGER) );
内容的提问来源于stack exchange,提问作者Kun Yue
相关产品推荐
相关产品推荐

