为什么要创建一个插入符分区boost ave函数?

问题描述 投票:0回答:1

我在使用具有2列和4.632.351行的df时遇到问题。

这些列是名称和性别。

我想计算重复的名称并添加到新列,所以我使用ave函数

data2$NmbCmpDup <- as.numeric(ave(data2$Nombre,data2$Nombre,  FUN = length))

但是要花很长时间,可能需要3个小时,所以我停止了运行过程。

然后用插入号创建了一个分区,因此我可以使用更少的行。

createDataPartition(data$Genero, p = 0.01, list=F)

所以我创建了一个1%的分区并使用ave函数

data.p = createDataPartition(data$Genero, p = 1, list=F)
data2 = data[data.p,]
data2$NmbCmpDup <- as.numeric(ave(data2$Nombre,data2$Nombre,  FUN = length))

然后,ave函数将提高到10秒。所以我尝试了5%,但速度仍然非常快,所以我添加了越来越多的百分比,直到制作了100%的分区,而ave函数仅用了2分钟。

[好,现在我想知道为什么..?有什么想法吗?

r data-science r-caret
1个回答
0
投票

该函数很慢,因为您不需要使用ave来获取长度。您可以表,然后填充列。以下是3个解决方案,它们应该比您拥有的解决方案快。另外,我不确定您的Nombre名称栏是一个因素还是一个字符。

第一个例子:

set.seed(100)
data2 = data.frame(Nombre = sample(LETTERS,2e6,replace=TRUE),
Genero = sample(c("M","F"),2e6,replace=TRUE),stringsAsFactors=FALSE)

这些功能,我认为data.table仍然不是最佳的,但是我们现在可以使用它:

f1 = function(data2){
data2$NmbCmpDup = as.numeric(ave(data2$Nombre,data2$Nombre,FUN=length))
data2
}
f2 = function(data2){
data2$NmbCmpDup = as.numeric(table(data2$Nombre)[data2$Nombre])
data2
}
f3 = function(data2){
tab = as.data.table(data2)[,.N,by=Nombre]
data2$NmbCmpDup = tab$N[match(data2$Nombre,tab$Nombre)]
data2
}

我们对其进行测试:

library(microbenchmark)
library(data.table)
Unit: milliseconds
      expr       min        lq     mean   median       uq      max neval cld
 f1(data2) 584.73459 626.12690 670.0398 643.3440 687.0022 911.2973   100   c
 f2(data2) 175.23440 196.36763 229.3775 213.6137 237.8333 407.0434   100  b 
 f3(data2)  73.35966  94.32614 119.9301 104.9643 119.7894 335.6455   100 a  

因此,仅使用table或data.table比ave函数要快得多。

© www.soinside.com 2019 - 2024. All rights reserved.