Шукайте "не містить" в DataFrame в пандах


142

Я здійснив пошук і не можу зрозуміти, як відфільтрувати кадр даних df["col"].str.contains(word), однак мені цікаво, чи є спосіб зробити зворотне: фільтрувати кадр даних за компліментом цього набору. наприклад: до ефекту !(df["col"].str.contains(word)).

Чи можна це зробити DataFrameметодом?

Відповіді:


264

Ви можете використовувати оператор invert (~) (який діє як не для булевих даних):

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]

Чи можна поєднувати це так? 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 як рішення цієї проблеми
Vishav Gupta

5

Сподіваюся, відповіді вже розміщені

Я додаю рамки, щоб знайти декілька слів і заперечувати ті з DataFrame .

Тут 'word1','word2','word3','word4'= список шаблонів для пошуку

df = DataFrame

column_a = Ім'я стовпця від df DataFrame

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)]

3

Додатково до відповіді nanselm2 ви можете використовувати 0замість False:

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

схоже, це також видалить усі рядки зNaN
bshelt141
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.