首页 > 解决方案 > stringr::str_extract_all - 如何提高速度/替代方案?

问题描述

我有数百个包含多个页面的文档,其中包含从网络上提取的文本。我正在尝试提取文本中出现的所有国家/地区名称,以及每个匹配/国家/地区名称前后的 10 个单词。

到目前为止,我使用了countrycode包含一个数据框的包,该数据框codelist包含基本上所有国家的名称(以及reprex这些名称的版本)。

我将这些名称拉到一个长向量中,用 OR 符号“|”折叠它 作为分隔符,并将生成的字符串用作 stringr's 中的正则表达式str_extract_all。总的来说,这种方法很有效,但是,我喜欢它的速度很慢。

在我的(平均)笔记本电脑(16 gig,i5-8625U)上,仅检查一个文档的前 1500 个字符需要 40 秒。在我所有的文档上运行脚本可能需要一天以上的时间。

因此,我的问题是——如何提高提取国名及其相邻词的速度?由于这是我经常需要的任务,因此我也很乐意使用其他工具(Julia?Python?)。

library(tidyverse)
library(countrycode)
library(rvest)
library(tictoc)

df_main <-c("http://docstore.ohchr.org/SelfServices/FilesHandler.ashx?enc=6QkG1d%2fPPRiCAqhKb7yhssh2tXWBbyLwahMw00Sn91Vx2CtIqUsxb8GHTWZijKzuMBGT4crbn9EZ8sIYVnIZ4cuyvgS8esYaZB%2bpIm6AjmiXFUTphoU1fK%2blmqzGzjoi8BFXLvYtOrKwuZsRFFTmN0umUat3QkQ%2bVArWqePYKE8%3d") %>%  
  enframe(name=NULL,
          value="doc_link")



fn_get_doc_text <- function(doc_link) {
  xml2::read_html(doc_link) %>% 
    rvest::html_text()
}

df_main <- df_main %>% 
  mutate(doc_text=map_chr(doc_link, possibly(fn_get_doc_text, otherwise="missing"))) %>% 
  mutate(doc_intro=str_sub(doc_text, end=1500) %>% str_squish())

df_country_patterns <- countrycode::codelist %>% 
  select(country.name.en) %>% 
  mutate(country_pattern=paste0("(\\S+\\s+){0,10}", country.name.en, "(\\s+\\S+){0,10}"))

vec_country_patterns <- df_country_patterns %>% 
  pull(country_pattern) %>% 
  paste(., collapse="|")

# stringr -----------------------------------------------------------------


tic()
df_main <- df_main %>% 
  mutate(countries_detected=str_extract_all(doc_intro, regex(vec_country_patterns, 
                                                            ignore_case = F,
                                                            dotall = T)))
toc()  
#> 41.34 sec elapsed

reprex 包(v0.3.0)于 2020-09-20 创建

标签: rregexstringr

解决方案


推荐阅读