【问题标题】:R Looking for fast solution to identify substrings in large vector of stringsR寻找快速解决方案来识别大字符串向量中的子字符串
【发布时间】:2020-02-20 12:12:52
【问题描述】:

我有一个带有子字符串的向量和一个带有文本的更大向量(有时是更长的字符串)。我想识别文本向量中的所有子字符串。我有一个简单的 for 循环解决方案,但这需要很长时间,因为我有大量数据。在我的代码中,第一个 for 循环需要大约 6 秒,而第二个循环需要 1.3 秒。 文本和子字符串是愚蠢的例子。在这里,一切都是一样的,但在我的示例中,数据帧中每一行的字符串都不同。我基本上想为每个子字符串存储相应文本的 ID。

编辑:为了澄清下面的问题,我想将子字符串与每个文本的开头进行匹配。这就是为什么我将文本限制为具有 df.substring$substringx 长度的子字符串。但是,子字符串的大小可以不同。

df <- data.frame(text = (rep("abcasdashgsdgsdfaasdaasdasdasdasdasdasdasdasasdaasdasdasdasdasdasdasddasssssssasdasdasdws",100000)),
                 id = seq(1:100000))
df$text <- as.character(df$text)
df <- rbind(df,data.frame(text = "gsdfasdasdasdasfoisnhfoiajdfoaisjdoiajndoiasjdoasijdaoisjdoaisjda",id=100001))

df.substring <- data.frame(substringx = rep("gsdf",200))
df.substring$substringx <- as.character(df.substring$substringx)
df.substring$id <- ""


before <- Sys.time()
for(i in 1:nrow(df.substring)){
  df.substring$id[i] <- paste(as.character(df$id[stringsim(df.substring$substringx[i],substr(df$text,1,nchar(df.substring$substringx[i]))) > 0.85]),collapse=";")
}
after <- Sys.time()
after - before


before <- Sys.time()
for(i in 1:nrow(df.substring)){
  df.substring$id[i] <- paste(as.character(df$id[df.substring$substringx[i] == substr(df$text,1,nchar(df.substring$substringx[i]))]),collapse=";")
}
after <- Sys.time()
after - before

如果有解决方案(对于每个 for 循环)只需要 1/10 的时间,我会很棒。

【问题讨论】:

  • 这段代码多久运行一次?
  • 我必须运行大约 50k 次。在我的真实数据中,带有文本和子字符串的向量实际上更大。目前,我的代码运行了好几天。这就是为什么我想让这部分更有效率。
  • 请澄清一下,您是否要查找每个子字符串出现在开头或任何位置的所有文本行?从您的代码来看,它似乎是前者,但从问题中并不明显。
  • 我希望我说得更清楚。请看上面。 (我只对正文的开头感兴趣)。

标签: r string substring


【解决方案1】:

如果您有许多长度相同的子字符串,您可以将部分substr(df$text,1,nchar(df.substring$substringx[i])) 全部制作一次,并在可以提高速度之前使用子字符串形式。

before <- Sys.time()
tt  <- df$text
for(n in sort(unique(nchar(df.substring$substringx)), decreasing=TRUE)) {
    tt  <- substr(tt,1,n)
    for(i in which(n == nchar(df.substring$substringx))) {
        df.substring$id[i] <- paste(as.character(
df$id[df.substring$substringx[i] == tt]),collapse=";")
    }
}
Sys.time() - before
#Time difference of 0.1532843 secs

#Compared to the faster solution of the question
before <- Sys.time()
for(i in 1:nrow(df.substring)){
  df.substring$id[i] <- paste(as.character(df$id[df.substring$substringx[i] == substr(df$text,1,nchar(df.substring$substringx[i]))]),collapse=";")
}
Sys.time() - before
#Time difference of 1.045545 secs

【讨论】:

  • 好的,我明白了。不幸的是,这些子串的长度变化很大。而且,即使对于这些愚蠢的数据,使用“stringsim”(5.4 对 6.3 秒)时也没有那么快
  • 哦,那很糟糕,长度不同。对于示例数据,与您在我的 PC 上的更快解决方案相比,时间可以减少到不到 15%。
猜你喜欢
  • 2021-03-14
  • 1970-01-01
  • 1970-01-01
  • 2011-04-27
  • 2019-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多