Обычно я делаю это, используя stringi
, следующим образом:
library(stringi)
Old <- df2[["vocabword"]]
New <- df2[["token"]]
stringi::stri_replace_all_regex(df1[["datalist"]],
"\\b"%s+%Old%s+%"\\b",
New,
vectorize_all = FALSE)
#[1] "wiki/Anarchist_schools_of_thought can differ fundamentally supporting anything from extreme wiki/Individualism to complete wiki/Collectivism"
#[2] "strains of anarchism have often been divided into the categories of wiki/Social_anarchism and wiki/Individualist_anarchism or similar dual classifications"
#[3] "the word is composed from the word wiki/Anarchy and the suffix wiki/-ism themselves derived respectively from the greek i.e"
#[4] "Anarchy from anarchos meaning one without rulers from the wiki/Privative prefix wiki/Alpha_privative an- i.e"
#[5] "authority sovereignty realm magistracy and the suffix or -ismos -isma from the verbal wiki/Infinitive suffix -izein"
#[6] "the first known use of this word was in 1539"
Теоретически, вы должны быть в состоянии получить разумное улучшение, распараллелив это правильно, но вы не сможете получить ничего лучше, чем Nx
ускорение (где N
= # доступных ядер). - Я догадываюсь, что сокращение времени выполнения с примерно 8 месяцев до 15 дней все еще не помогает вам в практическом смысле.
Однако, если у вас есть 14 миллионов потенциальных замен для создания более 90 миллионов строк, кажется, что может потребоваться принципиально иной подход. Какое максимальное количество слов в любом предложении?
Обновление: добавление примера кода для оценки потенциальных решений:
Добавление к вашим дополнительным предложениям с помощью stringi::stri_rand_lipsum()
и добавление дополнительных пар замены с помощью stringi::stri_rand_strings()
облегчает просмотр эффектов увеличения размера корпуса и словарного запаса на время выполнения.
С 1000 предложений:
- 1000 сменных пар: 3,9 секунды.
- 10000 сменных пар: 36,5 секунд.
- 100 000 сменных пар: 365,4 секунды.
Я не собираюсь пробовать 14 миллионов, но это должно помочь вам оценить, будут ли масштабироваться альтернативные методы.
library(stringi)
ExtraSentenceCount <- 1e3
ExtraVocabCount <- 1e4
Sentences <- c("wiki/anarchist_schools_of_thought can differ fundamentally supporting anything from extreme wiki/individualism to complete wiki/collectivism",
"strains of anarchism have often been divided into the categories of wiki/social_anarchism and wiki/individualist_anarchism or similar dual classifications",
"the word is composed from the word wiki/anarchy and the suffix wiki/-ism themselves derived respectively from the greek i.e",
"anarchy from anarchos meaning one without rulers from the wiki/privative prefix wiki/privative_alpha an- i.e",
"authority sovereignty realm magistracy and the suffix or -ismos -isma from the verbal wiki/infinitive suffix -izein",
"the first known use of this word was in 1539",
stringi::stri_rand_lipsum(ExtraSentenceCount))
vocabword <- c("anarchist_schools_of_thought", "individualism","collectivism" , "1965-66_nhl_season_by_team","social_anarchism","individualist_anarchism",
"anarchy","-ism","privative","privative_alpha", "1310_the_ticket", "infinitive",
"a",
stringi::stri_rand_strings(ExtraVocabCount,
length = sample.int(8, ExtraVocabCount, replace = TRUE),
pattern = "[a-z]"))
token <- c("Anarchist_schools_of_thought" ,"Individualism", "Collectivism", "1965-66_NHL_season_by_team", "Social_anarchism", "Individualist_anarchism" ,"Anarchy",
"-ism", "Privative" ,"Alpha_privative", "KTCK_(AM)" ,"Infinitive",
"XXXX",
stringi::stri_rand_strings(ExtraVocabCount,
length = 3,
pattern = "[0-9]"))
system.time({
Cleaned <- stringi::stri_replace_all_regex(Sentences, "\\b"%s+%vocabword%s+%"\\b", token, vectorize_all = FALSE)
})
# user system elapsed
# 36.652 0.070 36.768
head(Cleaned)
# [1] "wiki/Anarchist_schools_of_thought can differ fundamentally supporting anything from extreme wiki/Individualism 749 complete wiki/Collectivism"
# [2] "strains 454 anarchism have often been divided into the categories 454 wiki/Social_anarchism and wiki/Individualist_anarchism 094 similar dual classifications"
# [3] "the word 412 composed from the word wiki/Anarchy and the suffix wiki/-ism themselves derived respectively from the greek 190.546"
# [4] "Anarchy from anarchos meaning one without rulers from the wiki/Privative prefix wiki/Alpha_privative 358- 190.546"
# [5] "authority sovereignty realm magistracy and the suffix 094 -ismos -isma from the verbal wiki/Infinitive suffix -izein"
# [6] "the first known use 454 this word was 201 1539"
Обновление 2: Приведенный ниже метод не учитывает вероятность того, что у вас есть теги, которые являются подстроками другого - то есть wiki/Individualist
и wiki/Individualist_anarchism
могут дать вам ошибочные результаты. Единственный способ, которого я действительно знаю, чтобы избежать этого, - это использовать регулярное выражение / замену слов на полные слова, начинающиеся и сопровождаемые границами слов (\\b
), которые не могут основываться на фиксированной строке.
Один из вариантов, который может вселить в вас надежду, основан на том факте, что все необходимые замены заменены на префикс wiki/
. Если это так для вашего фактического использования, то мы можем воспользоваться этим и использовать фиксированные замены вместо регулярных выражений для замены полных слов, перед которыми следуют границы слов (\\b
). (это необходимо, чтобы избежать замены слова из словаря, например, "ism", когда оно встречается как часть более длинного слова)
Используя тот же список, что и выше:
prefixed_vocabword <- paste0("wiki/",vocabword)
prefixed_token <- paste0("wiki/",token)
system.time({
Cleaned <- stringi::stri_replace_all_fixed(Sentences, prefixed_vocabword, prefixed_token, vectorize_all = FALSE)
})
Это сокращает время выполнения до 10,4 секунд при 1000 предложениях и 10 000 заменах, но, поскольку время выполнения все еще растет линейно, для вашего размера данных все равно потребуются часы.