Как получить список соответствия шаблонов в регулярных выражениях с помощью str.contains? - PullRequest
2 голосов
/ 05 апреля 2020

У меня есть фрейм данных df, в котором есть текст в столбце Match_text. Я сопоставляю Match_text с terms с использованием граничного условия регулярного выражения \b. Я получаю ожидаемый результат, но мне также нужно распечатать образец, соответствующий df. В этом случае foo и baz совпадают с \b. Как я получаю эти термины также?

texts = ['foo abc', 'foobar xyz', 'xyz baz32', 'baz 45','fooz','bazzar','foo baz']
terms = ['foo','ball','baz','apple']
df = pd.DataFrame({'Match_text': texts})
pat = r'\b(?:{})\b'.format('|'.join(terms))
df[df['Match_text'].str.contains(pat)]

Вывод

    Match_text
0   foo abc
3   baz 45
6   foo baz

вместе с этим выводом мне также нужны foo, baz, и foo

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Немного многословно ИМХО, давайте узнаем, соответствует ли он вашему сценарию использования:

df['content'] = df[df['Match_text'].str.contains(pat)]
(df
 .dropna()
 .assign(temp = lambda x: x.content.str.split())
 .explode('temp')
 .reset_index()
 .assign(present=lambda x: x.loc[x.temp.isin(terms),'temp'])
 .dropna()
 .drop(['temp','content'],axis=1)
)

 index  Match_text  present
0   0   foo abc      foo
2   3   baz 45       baz
4   6   foo baz      foo
5   6   foo baz      baz

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

   M = df.loc[df['Match_text'].str.contains(pat)]

#create pattern
p = re.compile(pat)

#search for pattern in the column
results = [p.findall(text) for text in M.Match_text.tolist()]

#assign results to a new column
M = M.assign(content = results)

M

        Match_text  content
0        foo abc    [foo]
3        baz 45     [baz]
6        foo baz    [foo, baz]
0 голосов
/ 05 апреля 2020

Один из подходов заключается в добавлении нового столбца к текущему результирующему фрейму данных, который содержит только совпадающие термины со всеми другими несоответствующими словами:

terms_regex = r'(?:{})'.format('|'.join(terms))
df['Match_terms'] = re.sub(r'\s*\b(?!' + pat1 + r')\S+\b\s*', '', df['Match_text']

Для ясности здесь, регулярное выражение I используется для удаления несоответствующих слов:

\s*\b(?!(?:foo|ball|baz|apple))\S+\b\s*

Это будет соответствовать любому термину, который является не одним из ваших ключевых слов, вместе с необязательным окружающим пробелом, заменяя его пустой строкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...