我有一个代码
matrix<-outer(df$text, df1$regexp, str_count)
df超过1000个文本,每个约1500个符号 和df1有500个正则表达式否定表达式,如
(?<!(no|not|n`t|n’t|neither|never|no one|nobody|none|nor|nothing|nowhere|hardly|barely|scarcely|unlikely|seldom|rarely))[ ][aA][bB][aA][nN][dD][oO][nN]
所以我的代码运行了一个多小时
如何加速我的代码?
示例:
library(stringr)
df<-data.frame(names=c("text1","text2"), text=c("one two three four five","six seven eight nine ten"))
regex<-data.frame(names=c("1","2"), regexp=c("(?<!(no|not))[ ][oO][nN][eE]","(?<!(no|not))[ ][fF][iI][vV][eE]"))
matrix<-outer(df$text, as.character(regex$regexp), str_count)
我尝试与
并行运行代码library(stringr)
library(parallel)
no_cores <- detectCores() - 1
df<-data.frame(names=c("text1","text2"), text=c("one two three four five","six seven eight nine ten"))
regex<-data.frame(names=c("1","2"), regexp=c("(?<!(no|not))[ ][oO][nN][eE]","(?<!(no|not))[ ][fF][iI][vV][eE]"))
cl <- makeCluster(no_cores)
matrix<-parSapply(cl,regex$regexp, str_count, string=df$text)
stopCluster(cl)
现在我的4核PC上编码速度提高了40%
我改变了像Wiktor推荐的所有正则表达式,使用代码运行速度比使用旧正则表达式的并行代码快25%左右
(?<!n(?:[`’]t|e(?:ither|ver)|o(?:t| one|body|ne|r|thing|where){0,1})|hardly|barely|scarcely|unlikely|seldom|rarely)[ ][aA][bB][aA][nN][dD][oO][nN]
答案 0 :(得分:1)
stringr 中使用的正则表达式风格是ICU(因此,无法在regex101.com上测试它是否有效)并且这种风格不需要完全固定宽度的外观。在一些简单的情况下,它确实支持限制量词以及常规<select name="comuna" class="form-control" tabindex=8 id="comuna_select" required>
<option disabled selected style="font-color: #ccc;">Comuna</option>
<option value="Cachapoal/Codegua">Cachapoal / Codegua</option>
<option value="Cachapoal/Coinco">Cachapoal / Coinco</option>
</select>
<input id="datepicker" type="text" name="fecha" class="form-control" tabindex=9 placeholder="Click para seleccionar fecha" required/>
和*
(尽管后两者更像是一个错误,而不是一个功能,可能会在以后修复)。
所以,你的正则表达式运行缓慢,因为几个交替分支以相同的子串开始。这造成了过多的回溯。您需要确保每个分支在同一个位置不匹配。
使用
+
答案 1 :(得分:0)
预先正确创建数据(字符而不是因子)
df <- data.frame(names=c("text1","text2"),
text=c("one two three four five",
"six seven eight nine ten"),
stringsAsFactors=FALSE)
regex <- data.frame(names=c("1","2"),
regexp=c("(?<!(no|not))[ ][oO][nN][eE]",
"(?<!(no|not))[ ][fF][iI][vV][eE]"),
stringsAsFactors=FALSE)
R函数通常被矢量化&#39;,这意味着每个正则表达式都可以应用于字符串向量
str_count(pattern=regex$regex[1], string=df$text)
或
sapply(regex$regex, str_count, string=df$text)
例如,
> sapply(regex$regex, str_count, string=df$text)
(?<!(no|not))[ ][oO][nN][eE] (?<!(no|not))[ ][fF][iI][vV][eE]
[1,] 0 1
[2,] 0 0
可能这会在两个维度上线性扩展,但随着outer()
的增加,使用length(df$text)
的速度要快得多。