Искать «не содержит» в DataFrame в pandas

142

Я немного поискал и не могу понять, как отфильтровать фрейм данных df["col"].str.contains(word), однако мне интересно, есть ли способ сделать обратное: отфильтровать фрейм данных с помощью этого набора. например: эффект !(df["col"].str.contains(word)).

Можно ли это сделать с помощью DataFrameметода?

Стайтс
источник

Ответы:

264

Вы можете использовать оператор инвертирования (~) (который действует как не для логических данных):

new_df = df[~df["col"].str.contains(word)]

, где new_dfкопия, возвращенная RHS.

содержит также принимает регулярное выражение ...


Если приведенное выше вызывает ошибку ValueError, вероятно, причина в том, что у вас смешанные типы данных, поэтому используйте na=False:

new_df = df[~df["col"].str.contains(word, na=False)]

Или,

new_df = df[df["col"].str.contains(word) == False]
Энди Хейден
источник
1
Отлично! Я SQL-знаком с регулярными выражениями и думал, что в Python все по-другому - видел много статей re.compliesи сказал себе, что вернусь к этому позже. Похоже, я переусердствовал с поиском, и все именно так, как вы говорите
:)
6
Может быть, будет полезен полный пример: df[~df.col.str.contains(word)]возвращает копию исходного фрейма данных с исключенными строками, соответствующими слову.
Денис Голомазов
45

У меня тоже были проблемы с символом not (~), поэтому вот другой способ из другого потока StackOverflow :

df[df["col"].str.contains('this|that')==False]
nanselm2
источник
Можно ли это так сочетать? df[df["col1"].str.contains('this'|'that')==False and df["col2"].str.contains('foo'|'bar')==True]? Спасибо!
tommy.carstensen
Да, ты можешь. Здесь объясняется синтаксис: stackoverflow.com/questions/22086116/…
tommy.carstensen
Не забывайте, что если мы хотим переместить строки, содержащие "|" мы должны использовать "\" как df = df[~df["col"].str.contains('\|')]
Амир
9

Вы можете использовать Apply и Lambda для выбора строк, в которых столбец содержит что-либо в списке. Для вашего сценария:

df[df["col"].apply(lambda x:x not in [word1,word2,word3])]
Сыпь
источник
6

Мне пришлось избавиться от значений NULL перед использованием команды, рекомендованной Энди выше. Пример:

df = pd.DataFrame(index = [0, 1, 2], columns=['first', 'second', 'third'])
df.ix[:, 'first'] = 'myword'
df.ix[0, 'second'] = 'myword'
df.ix[2, 'second'] = 'myword'
df.ix[1, 'third'] = 'myword'
df

    first   second  third
0   myword  myword   NaN
1   myword  NaN      myword 
2   myword  myword   NaN

Теперь выполняем команду:

~df["second"].str.contains(word)

Я получаю следующую ошибку:

TypeError: bad operand type for unary ~: 'float'

Я избавился от значений NULL сначала с помощью dropna () или fillna () и без проблем повторил команду.

шореш
источник
1
Вы также можете использовать ~df["second"].astype(str).str.contains(word)для принудительного преобразования в str. См. Stackoverflow.com/questions/43568760/…
David C
1
@Shoresh, мы также можем использовать na = False как решение этой проблемы
Вишав Гупта,
5

Надеюсь ответы уже опубликованы

Я добавляю фреймворк, чтобы найти несколько слов и исключить их из dataFrame .

Здесь 'word1','word2','word3','word4'= список шаблонов для поиска

df = DataFrame

column_a = Имя столбца из DataFrame df

Search_for_These_values = ['word1','word2','word3','word4'] 

pattern = '|'.join(Search_for_These_values)

result = df.loc[~(df['column_a'].str.contains(pattern, case=False)]
Nursnaaz
источник
3

В дополнение к ответу nanselm2 вы можете использовать 0вместо False:

df["col"].str.contains(word)==0
U10-Forward
источник
похоже, это также удаляет все строки с помощьюNaN
bshelt141