У меня есть следующий фрейм данных, df:
id text
1 'a little table'
2 'blue lights'
3 'food and drink'
4 'build an atom'
5 'fast animals'
и список стоп-слов, то есть:
sw = ['a', 'an', 'and']
Я хочу удалить строки, содержащие хотя бы одно стоп-слово (как сами слова, а не как подстроки). То есть результат, который я хотел бы, это:
id text
2 'blue lights'
5 'fast animals'
Я пытался с:
df[~df['text'].str.contains('|'.join(sw), regex=True, na=False)]
но, похоже, это не работает, так как это работает с подстроками таким образом, а a является подстрокой всех текстов (кроме «синих огней»). Как мне изменить строку кода?

li = ['a', 'an', 'and']
for i in li:
for k in df.index:
if i in df.text[k].split():
df.drop(k,inplace=True)
Если вы хотите использовать str.contains, вы можете попробовать следующее:
import pandas as pd
data = {'id': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
'text': {0: "'a little table'", 1: "'blue lights'",
2: "'food and drink'", 3: "'build an atom'",
4: "'fast animals'"}}
df = pd.DataFrame(data)
sw = ['a', 'an', 'and']
res = df[~df['text'].str.contains(fr'\b(?:{"|".join(sw)})\b',
regex=True, na=False)]
print(res)
id text
1 2 'blue lights'
4 5 'fast animals'
В шаблоне регулярного выражения \b утверждает позицию на границе слова, а ?: в начале шаблона между (...) создает non-capturing group. Строго говоря, вы могли бы обойтись без ?:, но он подавляет Userwarning: «Этот шаблон ... имеет группы совпадений и т. д.».
`
вот один из способов сделать это
# '|'.join(sw) : creates a string with a |, to form an OR condition
# \\b : adds the word boundary to the capture group
# create a pattern surrounded by the word boundary and then
# filtered out what is found using loc
df.loc[~df['text'].str.contains('\\b('+ '|'.join(sw) + ')\\b' )]
ИЛИ
df[df['text'].str.extract('\\b('+ '|'.join(sw) + ')\\b' )[0].isna()]
id text
1 2 'blue lights'
4 5 'fast animals'
Вы также можете использовать собственный метод apply(),
def string_present(List,string):
return any(ele+' ' in string for ele in List)
df['status'] = df['text'].apply(lambda row: string_present(sw,row))
df[df['status']==False].drop(columns=['status'],axis=1)
Выход,
id text
1 2 blue lights
4 5 fast animals
Другое возможное решение, которое работает следующим образом:
Разделите каждую строку пробелом, создав список слов
Проверьте, не пересекается ли каждый из этих списков слов с sw.
Используйте результат для булевой индексации.
df[df['text'].str.split(' ').map(lambda x: set(x).isdisjoint(sw))]
Вывод:
id text
1 2 blue lights
4 5 fast animals
sw = ['a', 'an', 'and']
df1.loc[~df1.text.str.split(' ').map(lambda x:pd.Series(x).isin(sw).any())]
Пожалуйста, не публикуйте только код в качестве ответа, но также объясните, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением, как правило, более полезны и качественны, и с большей вероятностью привлекут положительные голоса.
Ваш код должен работать!