【发布时间】:2020-08-11 08:25:57
【问题描述】:
具有两列(3-grams 及其计数)的 data.table,在 ngrams 列上设置了一个键。 3-gram 是由空格分隔的三个单词的单个字符向量。
set.seed(20182)
create.ngrams <- function(){
w1 <- paste(sample(letters[1:5], 3, T), collapse = '')
w2 <- paste(sample(letters[1:5], 3, T), collapse = '')
w3 <- paste(sample(letters, 5, T), collapse = '')
ngram <- paste(c(w1, w2, w3), collapse = " ")
return(ngram)
}
dt <- data.table(ngrams = replicate(100000, create.ngrams()), N = sample.int(100, 100000, replace=T))
dt[ngrams %like% '^ada cab \\.*']
我需要得出的是,给定一个 2-gram,在以 2-gram 为词干的 3-gram 表中出现了多少个唯一的 3-gram?到目前为止的方法是过滤 3-gram 表并使用正则表达式和 data.table %like% 函数获取行数。不幸的是,documentation 声明 like 没有使用表键。
注意:当前实现不使用排序键。
这大大减慢了过滤速度:
dt[ngrams %like% '^ada cab \\.*']
ngrams N
1: ada cab jsfzb 33
2: ada cab rbkqz 43
3: ada cab oyohg 10
4: ada cab dahtd 87
5: ada cab qgmfb 8
6: ada cab ylyfl 13
7: ada cab izeje 83
8: ada cab fukov 12
microbenchmark(dt[ngrams %like% '^ada cab \\.*']))
Unit: milliseconds
expr min lq mean median uq max neval
dt[ngrams %like% "^ada cab \\\\.*"] 22.4061 23.9792 25.89883 25.0981 26.88145 34.7454 100
在我正在使用的实际表 (nrow = 46856038) 上,性能太慢而无法完成我的任务:
Unit: seconds
expr min lq mean median uq max neval
t[ngrams %like% "^on the \\\\.*"] 10.48471 10.57198 11.27199 10.77015 10.94827 17.42804 100
我可以做些什么来提高性能?我尝试与dplyr 一起工作,但收益似乎并不显着。
【问题讨论】:
-
冒险猜测。你有什么样的记忆?您是否可以将 3-gram 拆分为 3 列,然后键入这 3 列并在第 1&2 或 2&3 列中搜索 2-gram?
-
使用你的
set.seed我得到了不同的起始条件。这里还有别的吗? (R-3.5.3,win10)(此外,您在第一个和第二个代码块中都有一些错误的右括号。) -
@r2evans win10 和 R 版本 3.6.1,但不知道这些可能会影响种子启动条件。
-
我不知道他们会这样做,但是随着最近发布的 R-4.0,我想如果您使用的是该版本,这可能会有所不同。 *耸耸肩*
标签: r filter data.table regexp-like