Suchen Sie in Pandas in einem DataFrame nach "Nicht enthalten"

142

Ich habe einige Suchvorgänge durchgeführt und kann nicht herausfinden, wie ein Datenrahmen gefiltert werden df["col"].str.contains(word)soll. Ich frage mich jedoch, ob es eine Möglichkeit gibt, das Gegenteil zu tun: Filtern eines Datenrahmens nach dem Kompliment dieses Satzes. zB: zur Wirkung von !(df["col"].str.contains(word)).

Kann dies durch eine DataFrameMethode erfolgen?

Stites
quelle

Antworten:

263

Sie können den invert (~) -Operator verwenden (der sich wie ein nicht für boolesche Daten verhält):

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

, wo new_dfist die von RHS zurückgegebene Kopie.

enthält akzeptiert auch einen regulären Ausdruck ...


Wenn das oben Gesagte einen ValueError auslöst, liegt der Grund wahrscheinlich daran, dass Sie gemischte Datentypen haben. Verwenden Sie daher na=False:

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

Oder,

new_df = df[df["col"].str.contains(word) == False]
Andy Hayden
quelle
1
Perfekt! Ich bin mit Regex in SQL vertraut und dachte, dass es in Python anders ist. re.compliesIch habe viele Artikel mit gesehen und mir gesagt, dass ich später darauf zurückkommen würde. Sieht so aus, als hätte ich die Suche übertrieben und es ist genau so, wie du sagst
:)
6
Vielleicht wäre ein vollständiges Beispiel hilfreich: df[~df.col.str.contains(word)]Gibt eine Kopie des ursprünglichen Datenrahmens mit ausgeschlossenen Zeilen zurück, die mit dem Wort übereinstimmen.
Dennis Golomazov
45

Ich hatte auch Probleme mit dem nicht (~) -Symbol. Hier ist ein anderer Weg von einem anderen StackOverflow-Thread :

df[df["col"].str.contains('this|that')==False]
nanselm2
quelle
Kann es so kombiniert werden? df[df["col1"].str.contains('this'|'that')==False and df["col2"].str.contains('foo'|'bar')==True]? Vielen Dank!
Tommy.carstensen
Ja, du kannst. Die Syntax wird hier erklärt: stackoverflow.com/questions/22086116/…
tommy.carstensen
Nicht zu vergessen, wenn wir Zeilen verschieben möchten, die "|" enthalten wir sollten "\" wie df = df[~df["col"].str.contains('\|')]
Amir
9

Mit Apply und Lambda können Sie Zeilen auswählen, in denen eine Spalte Elemente in einer Liste enthält. Für Ihr Szenario:

df[df["col"].apply(lambda x:x not in [word1,word2,word3])]
Arash
quelle
6

Ich musste die NULL-Werte entfernen, bevor ich den von Andy oben empfohlenen Befehl verwenden konnte. Ein Beispiel:

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

Führen Sie nun den Befehl aus:

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

Ich erhalte folgende Fehlermeldung:

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

Ich habe die NULL-Werte zuerst mit dropna () oder fillna () entfernt und den Befehl ohne Probleme wiederholt.

Shoresh
quelle
1
Sie können auch die ~df["second"].astype(str).str.contains(word)Konvertierung in erzwingen str. Siehe stackoverflow.com/questions/43568760/…
David C
1
@Shoresh können wir auch na = False als Lösung für dieses Problem verwenden
Vishav Gupta
5

Ich hoffe die Antworten sind bereits gepostet

Ich füge das Framework hinzu, um mehrere Wörter zu finden und diese aus dataFrame zu negieren .

Hier 'word1','word2','word3','word4'= Liste der zu suchenden Muster

df = DataFrame

column_a = Ein Spaltenname von aus 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
quelle
3

Zusätzlich zur Antwort von nanselm2 können Sie 0anstelle von False:

df["col"].str.contains(word)==0
U10-Vorwärts
quelle
es sieht so aus auch entfernen alle Zeilen mitNaN
bshelt141