Python: замена слов в огромном тексте - PullRequest
1 голос
/ 02 июня 2011

У меня огромный текст и список слов ~ 10К. Какой самый быстрый способ в Python заменить все эти слова в тексте другим словом?

EDIT: Размер текста> 1 ГБ, текст написан человеком и «чрезвычайно размечен» (любые серии буквенно-цифровых символов и любые другие отдельные символы разбиты на новые токены)

количество слов> 10K, частота каждого слова в тексте равна 1 Слово замены одинаково во всех заменах. Python 2.5-2.7

Ответы [ 4 ]

3 голосов
/ 02 июня 2011

Формат ввода и информация о поиске / замене пар необходимы для уточнения этого ответа, если он близок к началу, но это будет мой первоначальный удар (при условии некоторой формы регулярности во входных данных, пробел ограничен вмой пример кода ниже).

replacements = {
  's1': 'r1',
  's2': 'r2'
  ...
}

with open('input.txt') as fhi, open('output.txt', 'w') as fho:
  for line in fhi:
    words = line.split(' ')

    fho.write(' '.join(map(lambda w: replacements.get(w, w), words))

    # Or as a list comprehension from the comments.
    fho.write(' '.join([replacements.get(w, w) for w in words]))

Идея в том, что мы будем перемещать данные в выходной файл из входного файла.Для каждого слова каждой строки мы проверяем, есть ли оно в нашем словаре замен.Мы извлекаем новое значение, если оно есть, или возвращаем слово без изменений с помощью метода dict.get(key[, default]).Это может быть не идеально, не обрабатывать знаки пунктуации, возможно, возникнут проблемы с входным файлом, который не был разбит на строки и т. Д., Но может быть способом начать работу.

1 голос
/ 02 июня 2011

Вау!Это совсем не тривиально.Вот идея:

Step 1: Quantize the text into words, signs etc. 
        The function quantize accepts text as an argument, 
        the output is the list of words and signs. 
        def quantize(text: str) -> list: 
            ...
        An inverse function that can construct the a from a given list:
        def dequantize(lst: list) -> str:
            ....

Step 2: Build a dictionary of quantized list, so that 
        d_rep[word] = word
        Then, use the replacements word lists to transform this dictionary as follows:
        d_rep[word] = replacement

Step 3: Go through every word in quantized list and replace it with a value from 
        d_rep dictionary. It might be the original word or a replacement. 

Step 4: Dequantize the list and restore the text. 

Это должно быть достаточно оптимальным, если у вас большой текст и огромное количество слов для поиска / замены.Удачи!Спросите, есть ли у вас вопросы по реализации.

Обновление: С одним заменяющим словом еще проще создать набор из списка слов «10К», а затем для каждого слова в квантованном списке, если слово в наборе, заменитьв этом списке.

В псевдопифон-коде:

qlist = quantize(text)

for i in range(0, len(qlist)):
    word = qlist[i]
    if word in wordlist_set:
        qlist[i] = 'replacement'

text = dequantize(qlist)
0 голосов
/ 02 июня 2011

Я бы предложил простой подход, заменяя одну строку за раз:

pattern1 = 'foo'
pattern2 = 'bar'

with open('input.txt') as input, open('output.txt', 'w') as output:
    for line in input:
        output.write(line.replace(pattern1, pattern2))
0 голосов
/ 02 июня 2011

Самый быстрый способ, если у вас достаточно памяти, может состоять в том, чтобы прочитать текст в виде строки и использовать регулярное выражение для поиска и выполнения замен:

def replace(matched):
    # Matched.group(0) is the word that was found
    # Return the replacement
    return "REPLACEMENT"

# The \b ensure that only whole words are matched.
text = re.sub(r"\b(%s)\b" % "|".join(words), replace, text)

Если у вас нет памятипопробуйте сделать это кусками, возможно:

# Read a chunk and a line to ensure that you're not truncating a word.
chunk = text_file.read(1024 ** 2) + text_file.readline()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...