Cari "tidak-mengandung" pada DataFrame di panda

142

Saya telah melakukan pencarian dan tidak tahu cara memfilter dataframe df["col"].str.contains(word), namun saya bertanya-tanya apakah ada cara untuk melakukan yang sebaliknya: filter dataframe dengan pujian set itu. misalnya: untuk efek !(df["col"].str.contains(word)).

Bisakah ini dilakukan melalui DataFramemetode?

stites
sumber

Jawaban:

264

Anda dapat menggunakan operator invert (~) (yang bertindak seperti bukan untuk data boolean):

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

, di mana new_dfsalinan dikembalikan oleh RHS.

mengandung juga menerima ekspresi reguler ...


Jika di atas melempar ValueError, alasannya mungkin karena Anda memiliki tipe data campuran, jadi gunakan na=False:

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

Atau,

new_df = df[df["col"].str.contains(word) == False]
Andy Hayden
sumber
1
Sempurna! Saya SQL-akrab dengan regex dan berpikir itu berbeda dengan Python - melihat banyak artikel dengan re.compliesdan berkata pada diri sendiri saya akan membahasnya nanti. Sepertinya saya menyesuaikan pencarian dan itu hanya seperti yang Anda katakan
:)
6
Mungkin contoh lengkap akan membantu: df[~df.col.str.contains(word)]mengembalikan salinan kerangka data asli dengan baris yang dikecualikan yang cocok dengan kata tersebut.
Dennis Golomazov
45

Saya mengalami masalah dengan simbol not (~) juga, jadi inilah cara lain dari utas StackOverflow lainnya :

df[df["col"].str.contains('this|that')==False]
nanselm2
sumber
Bisakah itu digabungkan seperti ini? df[df["col1"].str.contains('this'|'that')==False and df["col2"].str.contains('foo'|'bar')==True]? Terima kasih!
tommy.carstensen
Ya kamu bisa. Sintaksnya dijelaskan di sini: stackoverflow.com/questions/22086116/…
tommy.carstensen
Jangan lupa bahwa jika kita ingin mencari baris yang berisi "|" kita harus menggunakan "\" seperti df = df[~df["col"].str.contains('\|')]
Amir
9

Anda dapat menggunakan Terapkan dan Lambda untuk memilih baris di mana kolom berisi apa pun dalam daftar. Untuk skenario Anda:

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

Saya harus menyingkirkan nilai NULL sebelum menggunakan perintah yang direkomendasikan oleh Andy di atas. Sebuah contoh:

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

Sekarang jalankan perintah:

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

Saya mendapatkan kesalahan berikut:

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

Saya menyingkirkan nilai NULL menggunakan dropna () atau fillna () terlebih dahulu dan coba lagi perintah itu tanpa masalah.

Shoresh
sumber
1
Anda juga dapat menggunakan ~df["second"].astype(str).str.contains(word)untuk memaksa konversi str. Lihat stackoverflow.com/questions/43568760/…
David C
1
@Shoresh kita juga bisa menggunakan na = Salah sebagai solusi dari masalah ini
Vishav Gupta
5

Saya harap jawabannya sudah diposting

Saya menambahkan kerangka kerja untuk menemukan beberapa kata dan meniadakan kata-kata dari dataFrame .

Di sini 'word1','word2','word3','word4'= daftar pola untuk dicari

df = DataFrame

column_a = Nama kolom dari dari 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
sumber
3

Tambahan untuk jawaban nanselm2, Anda dapat menggunakan 0alih-alih False:

df["col"].str.contains(word)==0
U10-Maju
sumber
sepertinya ini juga menghapus baris apa pun denganNaN
bshelt141