Как соединить два слова, если им предшествовали определенные слова в предложениях в фрейме данных

У меня есть список твитов, содержащих слова отрицания, такие как «не, никогда, редко».

Я хочу преобразовать «нехорошо» в «нехорошо» (разделенные знаком подчеркивания).

Как я могу присоединиться ко всем «не» в твитах со словами, которые следуют за ними?

Я пытался сделать это, но это ничего не меняет, предложения остаются прежними без изменений.

def combine(negation_words, word_scan):
    if type(negation_words) != list:
        negation_words = [negation_words]  
    n_index = []
    
    for i in negation_words:
        index_replace = [(m.end(0)) for m in re.finditer(i,word_scan)]
        n_index += index_replace
    for rep in n_index:
        letters = [x for x in word_scan]
        letters[rep] = "_"
        word_scan = "".join(letters)
    return word_scan
negation_words = ["no", "not"]
word_scan = df
combine(negation_words, word_scan)
df['clean'] = df['tweets'].apply(lambda x: combine(str(x), word_scan))
df

Используйте re.sub().

Barmar 17.02.2023 01:24
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
Тонкая настройка GPT-3 с помощью Anaconda
Тонкая настройка GPT-3 с помощью Anaconda
Зарегистрируйте аккаунт Open ai, а затем получите ключ API ниже.
2
1
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать re.sub или Series.str.replace с регулярным выражением, чтобы найти любое слово в вашем списке negation_words, за которым следуют пробелы, и заменить его символом подчеркивания.

import re

negation_words = ["no", "not"]

escaped_words = "|".join(re.escape(word) for word in negation_words)
print(repr(escaped_words))
# 'no|not'

regex = fr"({escaped_words})\s+"
print(repr(regex))
# '(no|not)\\s+'

Объяснение регулярного выражения:

(no|not)\s+
(      )      : Capturing group. Whatever is matched inside is available to the replace string as \1 (since this is the first capturing group)
 no|not       : Either of (no, not). If there are more words, then any one of these words
        \s+   : One or more whitespace

Теперь вызовите Series.str.replace с case=False, чтобы выполнить поиск без учета регистра:

df = pd.DataFrame({'tweets': ['this is a tweet', 'this is not a tweet', 'no', 'Another tweet', 'Not another tweet', 'Tweet not']})

df['clean'] = df['tweets'].str.replace(regex, r'\1_', case=False, regex=True)

Который дает:

              tweets              clean
0    this is a tweet    this is a tweet
1        No tweeting        No_tweeting
2                 no                 no
3      Another tweet      Another tweet
4  Not another tweet  Not_another tweet
5          Tweet not          Tweet not

Соединить два слова после появления одного из negation_words немного сложнее:

regex = fr"({escaped_words})\s+(\w+)\s+"
print(repr(regex))
# '(no|not)\\s+(\\w+)\\s+'

Объяснение:

(no|not)\s+(\w+)\s+
(      )            : Capturing group. Whatever is matched inside is available to the replace string as \1 (since this is the first capturing group)
 no|not             : Either of (no, not). If there are more words, then any one of these words
        \s+         : One or more whitespace
           (   )    : Capturing group #2
            \w+     : One or more word characters
                \s+ : One or more whitespace
df = pd.DataFrame({'tweets': ['this is a tweet', 'this is not a tweet', 'no', 'Another tweet', 'Not another tweet', 'Tweet not']})

df['clean'] = df['tweets'].str.replace(regex, r'\1_\2_', case=False, regex=True)

Который дает:

                tweets                clean
0      this is a tweet      this is a tweet
1  this is not a tweet  this is not_a_tweet
2                   no                   no
3        Another tweet        Another tweet
4    Not another tweet    Not_another_tweet
5            Tweet not            Tweet not

@ZulfiA re.escape экранирует любые специальные символы при вводе, например. (, [ и т. д., чтобы их особое значение игнорировалось, и они считались буквальными символами. Это не обязательно для конкретного negation_words, который вы указали в своем вопросе, но полезно для обобщения подхода к случаям, когда могут существовать такие специальные символы. Если ваш исходный фрейм данных содержит весь текст в нижнем регистре, вы можете опустить аргумент case, но его не помешает сохранить.

Pranav Hosangadi 17.02.2023 04:59

Так что все в порядке, если я удалю экранированные слова, верно? в данных моих твитов нет специальных символов, потому что я уже очистил их все :) и получил его предупреждение :FutureWarning: Значение регулярного выражения по умолчанию изменится с True на False в будущей версии. Что это значит?

Zulfi A 17.02.2023 05:37

Недопустимо удалять escaped_words, потому что эта строка также соединяет все слова с вертикальной чертой, что в регулярном выражении означает word1 or word2 or word3 or .... вы можете изменить его на '|'.join(negation_words), но, честно говоря, это не будет иметь значения, если у вас нет специальных символов.

Pranav Hosangadi 17.02.2023 05:41

Предупреждение связано с тем, что функция str.replace имеет аргумент regex, который по умолчанию равен true. Поскольку это будет изменено в будущей версии False, вы можете явно указать это, чтобы удалить предупреждение @ZulfiA.

Pranav Hosangadi 17.02.2023 05:42

Ага, понятно! что, если я хочу объединить слова с двумя словами, которые следуют за словами отрицания? пример: вместо "некрасиво" я хочу сделать так "некрасиво_действительно_".

Zulfi A 17.02.2023 06:05

Затем вы просто добавляете регулярное выражение, чтобы оно соответствовало слову после \s+ в regex, см. stackoverflow.com/a/20956093/843953

Pranav Hosangadi 17.02.2023 06:50

Я думаю, что это немного отличается от того, что я ищу :( можете ли вы объяснить, что означает «r'\1_'»? Большое спасибо!

Zulfi A 17.02.2023 07:21

R обозначает необработанный строковый литерал. \1 означает первую группу захвата (которая заключена в круглые скобки, в данном случае negatiin_word присутствует в тексте), а _ — буквальное подчеркивание. Завтра я обновлю свой ответ, чтобы он соответствовал двум словам

Pranav Hosangadi 17.02.2023 07:24

@ZulfiA смотрите мой обновленный ответ, чтобы захватить два слова и соединить их с подчеркиванием

Pranav Hosangadi 17.02.2023 19:41

Я не могу отблагодарить вас за вашу помощь. хорошего дня!

Zulfi A 19.02.2023 01:31

Другие вопросы по теме