我有一个大的(约450万条记录)数据框,并且有几列已经通过散列进行匿名处理,我没有密钥,但我确实希望将它们重新编号为更易读的内容以帮助分析
为此,例如,我推断出'campaignID'在4.5条记录中有161个独特元素,并创建了一个矢量来保存这些元素。然后我尝试编写一个FOR / IF循环来使用唯一元素向量搜索完整数据集 - 对于'campaignID'的每个值,它将根据唯一元素向量进行检查,当它找到匹配时,它返回唯一元素向量的索引值作为新的广告系列ID。
campaigns_length <- length(unique_campaign)
dataset_length <- length(dataset$campaignId)
for (i in 1:dataset_length){
for (j in 1:campaigns_length){
if (dataset$campaignId[[i]] == unique_campaign[[j]]){
dataset$campaignId[[i]] <- j
}}}
问题当然是,虽然它有效但需要很长时间 - 我必须在12小时后停止它!任何人都可以想到更好,更快,计算更便宜的更好的方法吗?
答案 0 :(得分:1)
您可以使用match
。
dataset$campaignId <- match(dataset$campaignId, unique_campaign)
请参阅Is there an R function for finding the index of an element in a vector?
答案 1 :(得分:1)
在这种情况下,您可能会因使用data.table
包而受益:
library(data.table)
n = 10000000
unique_campaign = sample(1:10000, 169)
dataset = data.table(
campaignId = sample(unique_campaign, n, TRUE),
profit = round(runif(n, 100, 1000))
)
dataset[, campaignId := match(campaignId, unique_campaign)]
此示例包含1000万行,只需几秒钟即可运行。
答案 2 :(得分:0)
你可以避免使用类似字典结构的内部循环:
id_dict = list()
for (id in 1:unique_campaign) {
id_dict[[ unique_campaign[[id]] ]] = id
}
for (i in 1:dataset_length) {
dataset$campaignId[[i]] = id_dict[[ dataset$campaignId[[i]] ]]
}
如指出的in this post,列表没有O(1)访问权限,因此它不会将所需的时间除以161,而是根据列表中ID的重新分配,将其除以较小的因子。
此外,您的代码速度如此之慢的主要原因是因为您使用的是效率低下的列表(如果dataset$campaignId[[i]]
很大,单独使用i
会花费很多时间)。看一下提供O(1)元素访问的hash package(另请参阅this thread on hashed structures in R)