Wyszukaj „nie zawiera” w DataFrame w pandach

156

Zrobiłem kilka poszukiwań i nie mogę dowiedzieć się, jak filtrować ramkę danych df["col"].str.contains(word), jednak zastanawiam się, czy istnieje sposób na odwrócenie: filtruj ramkę danych według komplementu tego zestawu. np .: z efektem !(df["col"].str.contains(word)).

Czy można to zrobić DataFramemetodą?

stites
źródło

Odpowiedzi:

295

Możesz użyć operatora inwersji (~) (który działa jak nie dla danych boolowskich):

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

, gdzie new_dfjest kopia zwrócona przez RHS.

zawiera również akceptuje wyrażenie regularne ...


Jeśli powyższe zgłasza błąd ValueError, przyczyną jest prawdopodobnie mieszane typy danych, więc użyj na=False:

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

Lub,

new_df = df[df["col"].str.contains(word) == False]
Andy Hayden
źródło
1
Idealny! Znam SQL regex i pomyślałem, że w Pythonie jest inaczej - widziałem wiele artykułów re.compliesi powiedziałem sobie, że do tego dojdę później. Wygląda na to, że przeszedłem wyszukiwanie i jest tak, jak mówisz
:)
6
Może df[~df.col.str.contains(word)]przydałby się pełny przykład: zwraca kopię oryginalnej ramki danych z wykluczonymi wierszami pasującymi do słowa.
Dennis Golomazov
50

Miałem również problem z symbolem not (~), więc oto inny sposób z innego wątku StackOverflow :

df[df["col"].str.contains('this|that')==False]
nanselm2
źródło
Czy można to łączyć w ten sposób? df[df["col1"].str.contains('this'|'that')==False and df["col2"].str.contains('foo'|'bar')==True]? Dzięki!
tommy.carstensen
Tak, możesz. Składnia jest wyjaśniona tutaj: stackoverflow.com/questions/22086116/…
tommy.carstensen
Nie zapominajmy, że jeśli chcemy rwprzenieść wiersze zawierające "|" powinniśmy użyć "\" jak df = df[~df["col"].str.contains('\|')]
Amir
9

Możesz użyć Zastosuj i Lambda, aby wybrać wiersze, w których kolumna zawiera cokolwiek z listy. W Twoim scenariuszu:

df[df["col"].apply(lambda x:x not in [word1,word2,word3])]
Wysypka
źródło
6

Musiałem pozbyć się wartości NULL przed użyciem polecenia zalecanego przez Andy'ego powyżej. Przykład:

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

Teraz uruchamiam polecenie:

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

Otrzymuję następujący błąd:

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

Pozbyłem się wartości NULL za pomocą dropna () lub fillna () najpierw i ponowiłem polecenie bez problemu.

Shoresh
źródło
1
Możesz również użyć, ~df["second"].astype(str).str.contains(word)aby wymusić konwersję do str. Zobacz stackoverflow.com/questions/43568760/…
David C
1
@Shoresh możemy również użyć na = False jako rozwiązania tego problemu
Vishav Gupta
5

Mam nadzieję, że odpowiedzi zostały już opublikowane

Dodaję ramy, aby znaleźć wiele słów i zanegować te z dataFrame .

Here 'word1','word2','word3','word4'= lista wzorców do wyszukania

df = DataFrame

column_a = Nazwa kolumny z 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
źródło
3

Oprócz odpowiedzi nanselm2 możesz użyć 0zamiast False:

df["col"].str.contains(word)==0
U10-Forward
źródło
wygląda na to, że to również usuwa wszystkie wiersze zNaN
bshelt141