Saya memfilter baris dalam kerangka data dengan nilai dalam dua kolom.
Untuk beberapa alasan operator OR berperilaku seperti yang saya harapkan dari operator AND dan sebaliknya.
Kode tes saya:
import pandas as pd
df = pd.DataFrame({'a': range(5), 'b': range(5) })
# let's insert some -1 values
df['a'][1] = -1
df['b'][1] = -1
df['a'][3] = -1
df['b'][4] = -1
df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a != -1) | (df.b != -1)]
print pd.concat([df, df1, df2], axis=1,
keys = [ 'original df', 'using AND (&)', 'using OR (|)',])
Dan hasilnya:
original df using AND (&) using OR (|)
a b a b a b
0 0 0 0 0 0 0
1 -1 -1 NaN NaN NaN NaN
2 2 2 2 2 2 2
3 -1 3 NaN NaN -1 3
4 4 -1 NaN NaN 4 -1
[5 rows x 6 columns]
Seperti yang Anda lihat, AND
operator menjatuhkan setiap baris di mana setidaknya satu nilai sama -1
. Di sisi lain, OR
operator mengharuskan kedua nilai sama -1
untuk menjatuhkannya. Saya mengharapkan hasil yang justru sebaliknya. Adakah yang bisa menjelaskan perilaku ini?
Saya menggunakan panda 0.13.1.
python
pandas
boolean-logic
Wojciech Walczak
sumber
sumber
df.query
danpd.eval
sepertinya cocok untuk kasus penggunaan ini. Untuk informasi tentangpd.eval()
keluarga fungsi, fitur dan kasus penggunaannya, silakan kunjungi Evaluasi Ekspresi Dinamis di pandas menggunakan pd.eval () .Jawaban:
Betul sekali. Ingatlah bahwa Anda menulis kondisi dalam kaitannya dengan apa yang ingin Anda pertahankan , bukan apa yang ingin Anda hapus. Untuk
df1
:Anda mengatakan "pertahankan baris yang
df.a
bukan -1 dandf.b
bukan -1", yang sama dengan menghapus setiap baris yang setidaknya satu nilainya adalah -1.Untuk
df2
:Anda mengatakan "pertahankan baris yang salah satu
df.a
ataudf.b
bukan -1", yang sama dengan menghapus baris di mana kedua nilai adalah -1.PS: akses berantai seperti
df['a'][1] = -1
dapat membuat Anda mendapat masalah. Lebih baik membiasakan diri menggunakan.loc
dan.iloc
.sumber
DataFrame.query()
bekerja dengan baik di sini juga.df.query('a != -1 or b != -1')
.&
dan|
lebihand
danor
?and
danor
memiliki semantik Python dasar yang tidak dapat dimodifikasi.&
dan|
, di sisi lain, memiliki metode khusus terkait yang mengontrol perilaku mereka. (Dalam string kueri, tentu saja, kami bebas menerapkan penguraian apa pun yang kami suka.)df[True & False]
gagal tetapidf[(True) & (False)]
berhasil (tidak diuji pada contoh ini)Anda dapat menggunakan query () , yaitu:
sumber
Sedikit teori logika matematika di sini:
"NOT a AND NOT b" sama dengan "NOT (a OR b)" , jadi:
"a NOT -1 AND b NOT -1" setara dengan "NOT (a is -1 OR b is -1)" , yang merupakan kebalikan dari (Complement) dari "(a is -1 OR b is -1)" .
Jadi jika Anda ingin hasil yang berlawanan, df1 dan df2 harus seperti di bawah ini:
sumber