Bagaimana saya bisa mencapai setara dengan SQL IN
dan NOT IN
?
Saya memiliki daftar dengan nilai yang diperlukan. Inilah skenarionya:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = ['UK','China']
# pseudo-code:
df[df['countries'] not in countries]
Cara saya saat ini melakukan ini adalah sebagai berikut:
df = pd.DataFrame({'countries':['US','UK','Germany','China']})
countries = pd.DataFrame({'countries':['UK','China'], 'matched':True})
# IN
df.merge(countries,how='inner',on='countries')
# NOT IN
not_in = df.merge(countries,how='left',on='countries')
not_in = not_in[pd.isnull(not_in['matched'])]
Tapi ini seperti lumpur yang mengerikan. Adakah yang bisa memperbaikinya?
python
pandas
dataframe
sql-function
LondonRob
sumber
sumber
Jawaban:
Anda bisa menggunakannya
pd.Series.isin
.Untuk penggunaan "IN":
something.isin(somewhere)
Atau untuk "NOT IN":
~something.isin(somewhere)
Sebagai contoh yang berhasil:
sumber
isin
ditambahkan pada .13.df = pd.Series({'countries':['US','UK','Germany','China']})
df
, baik milikku maupun miliknya, adalah aDataFrame
.countries
adalah daftar.df[~df.countries.isin(countries)]
menghasilkanDataFrame
, bukan aSeries
, dan tampaknya berfungsi kembali di 0.11.0.dev-14a04dd.countries
variabel. Nah, OP yang melakukannya, dan itu diwariskan, tetapi sesuatu telah dilakukan dengan buruk sebelumnya tidak membenarkan melakukannya dengan buruk sekarang.Solusi alternatif yang menggunakan metode .query () :
sumber
query
tidak lagi eksperimental.Penawaran panda dua metode:
Series.isin
danDataFrame.isin
untuk Seri dan DataFrames, masing-masing.Filter DataFrame Berdasarkan pada ONE Column (juga berlaku untuk Seri)
Skenario yang paling umum adalah menerapkan
isin
kondisi pada kolom tertentu untuk memfilter baris dalam DataFrame.Series.isin
menerima berbagai jenis sebagai input. Berikut ini adalah semua cara yang sah untuk mendapatkan yang Anda inginkan:Filter pada BANYAK Kolom
Terkadang, Anda ingin menerapkan cek keanggotaan 'dalam' dengan beberapa istilah pencarian di beberapa kolom,
Untuk menerapkan
isin
kondisi pada kedua kolom "A" dan "B", gunakanDataFrame.isin
:Dari ini, untuk mempertahankan baris di mana setidaknya satu kolom berada
True
, kita dapat menggunakanany
sepanjang sumbu pertama:Perhatikan bahwa jika Anda ingin mencari setiap kolom, Anda cukup menghilangkan langkah pemilihan kolom dan lakukan
Demikian pula, untuk mempertahankan baris di mana SEMUA kolom berada
True
, gunakanall
dengan cara yang sama seperti sebelumnya.Terkemuka Mention:
numpy.isin
,query
, daftar comprehensions (data string)Selain metode yang dijelaskan di atas, Anda juga dapat menggunakan numpy setara:
numpy.isin
.Mengapa itu layak dipertimbangkan? Fungsi NumPy biasanya sedikit lebih cepat daripada panda yang setara karena overhead yang lebih rendah. Karena ini adalah operasi elementwise yang tidak bergantung pada penyelarasan indeks, ada beberapa situasi di mana metode ini bukan pengganti yang tepat untuk panda '
isin
.Rutinitas panda biasanya berulang saat bekerja dengan string, karena operasi string sulit untuk vectorise. Ada banyak bukti yang menunjukkan bahwa pemahaman daftar akan lebih cepat di sini. . Kami menggunakan
in
cek sekarang.Namun, jauh lebih sulit untuk ditentukan, jadi jangan menggunakannya kecuali Anda tahu apa yang Anda lakukan.
Terakhir, ada juga
DataFrame.query
yang telah dibahas dalam jawaban ini . numexpr FTW!sumber
Saya biasanya melakukan penyaringan generik pada baris seperti ini:
sumber
Saya ingin memfilter baris dfbc yang memiliki BUSINESS_ID yang juga ada di BUSINESS_ID dari dfProfilesBusIds
sumber
Menyusun kemungkinan solusi dari jawaban:
Untuk IN:
df[df['A'].isin([3, 6])]
Untuk TIDAK DI:
df[-df["A"].isin([3, 6])]
df[~df["A"].isin([3, 6])]
df[df["A"].isin([3, 6]) == False]
df[np.logical_not(df["A"].isin([3, 6]))]
sumber
logical_not
setara dengan~
operator.terapkan dalam :
mengimplementasikan tidak seperti di negara-negara lain:
sumber