R语言data.table如何高效识别词序颠倒的重复职业名称
大体积data.table词序颠倒职业条目高效去重方案
问题场景
需对存储职业名称列的data.table数据集做去重,识别规则为:组成词语完全一致但词序颠倒的条目属于同一职业的不同写法,仅保留单条记录即可。例如writer advertising与advertising writer属于重复项,需去重。
简化示例
输入数据集结构:
data = data.table( ID = as.character(c("advertisings writer","writer advertisings","setter","drill setter","setter drill","agent claims","claims agent","engineer")) )
预期去重结果:
data_result = data.table( ID = as.character(c("advertisings writer","setter","drill setter","agent claims","engineer")) )
现有实现的性能瓶颈
当前采用的逐ID拆词、生成逐词长表、全局排序、聚合回原条目再去重的方案,在大体积数据集下耗时过长,核心代码如下:
data[,b:= strsplit(ID," ")] data <- data[,.(b=unlist(b)),by = setdiff(names(data),'b')] setorderv(data,cols=c("ID","b")) data <- data[,bb:=list(list(unique(b))),by="ID"][,.SD[1],by=c("ID"),.SDcols=c("bb")] data[,b:=lapply(bb,paste,collapse=' ')] data[,b:=unlist(b)] unique(data,by="b")
该方案的核心耗时来源是将所有条目拆分为逐词的长表后做全局操作,数据量会膨胀为原条目拆词后的总词数规模,内存和排序开销都会成倍上升。
优化后高效实现方案
优化核心思路:跳过长表拆分的冗余环节,直接为每个职业条目生成词序无关的标准化对比键——将每个条目按空格拆分为单个词语,把词语按字典序重新拼接生成对比键,词序颠倒的条目会生成完全相同的对比键,仅需按该键去重即可,全程无数据维度膨胀。
实现代码:
library(data.table) # 为每个条目生成排序后的标准化对比键 data[, norm_key := sapply(strsplit(ID, " "), function(words) paste(sort(words), collapse = " "))] # 按标准化键分组去重,保留每组首次出现的原职业名称 result <- unique(data, by = "norm_key")[, .(ID)]
方案适配性说明
- 单词语职业条目(如
setter、engineer)拆词排序后与原文本一致,不会被误判为重复项 - 多词语职业只要组成词语完全一致、仅词序调换,就会生成相同的
norm_key,被准确识别为重复项 - 全程在原数据维度完成操作,无逐词长表的生成开销,内存占用和计算耗时较原方案可降低一个数量级以上
内容的提问来源于stack exchange,提问作者Miguel
相关产品推荐
相关产品推荐

