Rechercher «ne contient pas» sur un DataFrame dans les pandas


142

J'ai fait des recherches et je ne peux pas comprendre comment filtrer un dataframe par df["col"].str.contains(word), mais je me demande s'il existe un moyen de faire l'inverse: filtrer un dataframe par le compliment de cet ensemble. par exemple: à l'effet de !(df["col"].str.contains(word)).

Cela peut-il être fait par une DataFrameméthode?

Réponses:


264

Vous pouvez utiliser l'opérateur invert (~) (qui agit comme un pas pour les données booléennes):

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

, où new_dfest la copie retournée par RHS.

contient aussi accepte une expression régulière ...


Si ce qui précède génère une ValueError, la raison est probablement due au fait que vous avez des types de données mixtes, utilisez donc na=False:

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

Ou,

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

1
Parfait! Je connais SQL avec regex et je pensais que c'était différent en Python - j'ai vu beaucoup d'articles avec re.complieset je me suis dit que j'y reviendrais plus tard. On dirait que je suradapte la recherche et c'est comme vous le dites
:)

6
Un exemple complet serait peut-être utile: df[~df.col.str.contains(word)]renvoie une copie du dataframe d'origine avec les lignes exclues correspondant au mot.
Dennis Golomazov

45

J'avais également des problèmes avec le symbole not (~), alors voici une autre façon d'un autre thread StackOverflow :

df[df["col"].str.contains('this|that')==False]

Peut-il être combiné comme ça? df[df["col1"].str.contains('this'|'that')==False and df["col2"].str.contains('foo'|'bar')==True]? Merci!
tommy.carstensen

Oui, vous pouvez. La syntaxe est expliquée ici: stackoverflow.com/questions/22086116/…
tommy.carstensen

Ne pas oublier que si nous voulons rwmove les lignes qui contiennent "|" nous devrions utiliser "\" comme df = df[~df["col"].str.contains('\|')]
Amir

9

Vous pouvez utiliser Apply et Lambda pour sélectionner des lignes dans lesquelles une colonne contient tout élément d'une liste. Pour votre scénario:

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

6

J'ai dû me débarrasser des valeurs NULL avant d'utiliser la commande recommandée par Andy ci-dessus. Un exemple:

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

Maintenant, exécutez la commande:

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

J'obtiens l'erreur suivante:

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

Je me suis débarrassé des valeurs NULL en utilisant d'abord dropna () ou fillna () et j'ai réessayé la commande sans problème.


1
Vous pouvez également utiliser ~df["second"].astype(str).str.contains(word)pour forcer la conversion en str. Voir stackoverflow.com/questions/43568760/…
David C

1
@Shoresh, nous pouvons également utiliser na = False comme solution à ce problème
Vishav Gupta

5

J'espère que les réponses sont déjà postées

J'ajoute le cadre pour trouver plusieurs mots et annuler ceux de dataFrame .

Ici 'word1','word2','word3','word4'= liste des motifs à rechercher

df = DataFrame

column_a = Un nom de colonne de 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)]

3

En plus de la réponse de nanselm2, vous pouvez utiliser à la 0place de False:

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

il semble que ceci supprime également toutes les lignes avecNaN
bshelt141
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.