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

У меня есть большой набор данных all_transcripts с почти 3 миллионами строк. Один из столбцов msgText содержит письменные сообщения.

>>> all_transcripts['msgText']

['this is my first message']
['second message is here']
['this is my third message']

Кроме того, у меня есть список из 200+ слов, который называется gemeentes.

>>> gemeentes
['first','second','third' ... ]

Если слово в этом списке содержится в msgText, я хочу заменить его другим словом. Для этого я создал функцию:

def replaceCity(text):
    newText = text.replace(plaatsnaam, 'woonplaats')
    return str(newText)

Итак, мой желаемый результат будет выглядеть так:

['this is my woonplaats message']
['woonplaats message is here']
['this is my woonplaats message']

В настоящее время я просматриваю список и для каждого элемента в моем списке применяю функцию replaceCity.

for plaatsnaam in gemeentes:
    global(plaatsnaam)
    all_transcripts['filtered_text'] = test.msgText.apply(replaceCity)

Однако это занимает очень много времени, поэтому не кажется эффективным. Есть ли более быстрый способ выполнить эту задачу?


Этот пост (Алгоритм поиска нескольких совпадений строк) похож, однако моя проблема отличается, потому что:

  • здесь есть только один большой кусок текста, а у меня есть набор данных с множеством разных строк

  • Я хочу заменить слова, а не просто найти слова.


person Emil    schedule 01.05.2019    source источник
comment
Вы пробовали регулярное выражение с лямбда-функциями pandas ??   -  person Patel    schedule 01.05.2019


Ответы (1)


Предполагая, что all_transcripts является пандой DataFrame:

all_transcripts['msgText'].str.replace('|'.join(gemeentes),'woonplaats')

Пример:

all_transcripts = pd.DataFrame([['this is my first message'],
                                ['second message is here'],
                                ['this is my third message']],
                               columns=['msgText'])
gemeentes = ['first','second','third']

all_transcripts['msgText'].str.replace('|'.join(gemeentes),'woonplaats')

выходы

0    this is my woonplaats message
1       woonplaats message is here
2    this is my woonplaats message
person Dan    schedule 01.05.2019
comment
Спасибо! С помощью этого кода он заменяет каждое вхождение слова, даже если оно содержится в другом слове. Знаете ли вы, есть ли способ сделать это только для целых слов? Например. если бы у меня были предложения «Это первый раз для меня» и «А как насчет второго раза», оно заменяет оба предложения: «Это время вунплат для меня» и «А как насчет времени вунплатс». Однако я хочу заменить только те экземпляры, в которых заменены слова, полностью содержащие слово. Таким образом, вывод будет таким: «Это первый раз для меня» и «Как насчет времени вунплаатс». Вы знаете, как это сделать? - person Emil; 01.05.2019
comment
Я добавил пробелы вокруг своих слов в gemeentes, так что теперь это работает! - person Emil; 01.05.2019
comment
@emil pandas .str.replace принимает регулярное выражение, так что может быть более аккуратный способ найти слово. Я бы посоветовал оставить gemeentes как было, но изменить соединение с '|'.join(gemeentes) на pattern = r'\s*' + r'\s*|\s*'.join(gemeentes) + r'\s*' and then .str.replace(pattern, 'woonplaats'). Таким образом, вы нажмете все пробелы, а не только отдельные пробелы. Вы, вероятно, также захотите учитывать слова, оканчивающиеся точками, вопросительными знаками и т. д. Но я уверен, что если вы будете искать целые слова в регулярном выражении, вы найдете хорошее решение. - person Dan; 01.05.2019
comment
.str.replace(pattern, 'woonplaats') не работает. Он по-прежнему заменяет части слов, а также заменяет пробелы вокруг слов. Разве вы не должны использовать границу слова регулярного выражения? - person Superdooperhero; 21.07.2019
comment
pattern = r'\b' + '|'.join(gemeentes) + r'\b' работал на меня. - person Superdooperhero; 21.07.2019