データフレームの行を2列の値でフィルタリングしています。
何らかの理由で、OR演算子は、AND演算子の動作を期待するように動作し、その逆も同様です。
私のテストコード:
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 (|)',])
そして結果:
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]
ご覧のとおり、AND
演算子は、少なくとも1つの値が-1
に等しいすべての行を削除します。一方、OR
演算子を使用するには、両方の値を-1
と等しくして削除する必要があります。私はまったく逆の結果を期待しています。誰でもこの動作を説明できますか?
パンダ0.13.1を使用しています。
ご覧のとおり、AND演算子は、少なくとも1つの値が-1に等しいすべての行をドロップします。一方、OR演算子では、両方の値を-1に設定して削除する必要があります。
そのとおり。ドロップしたいものではなく、keepにしたいものに関して条件を書いていることに注意してください。 df1
の場合:
df1 = df[(df.a != -1) & (df.b != -1)]
「df.a
が-1ではなく、df.b
が-1ではない行を保持する」と言っています。これは、少なくとも1つの値が-1であるすべての行を削除するのと同じです。
df2
の場合:
df2 = df[(df.a != -1) | (df.b != -1)]
「df.a
またはdf.b
のいずれかが-1でない行を保持する」と言っています。これは、両方の値が-1である行を削除することと同じです。
PS:df['a'][1] = -1
のような連鎖アクセスは問題を引き起こす可能性があります。 .loc
と.iloc
を使用する習慣を身に付けた方がよいでしょう。
query() を使用できます。つまり:
df_filtered = df.query('a == 4 & b != 2')
少し数学論理理論ここ:
"NOT a AND NOT b"は "NOT(a OR bと同じです) "、したがって:
"a NOT -1 AND b NOT -1"は "と同等です(aは-1 OR bは-1) "です。これは)の反対(補数)です(aは-1 OR bは-1) "です。
したがって、正反対の結果が必要な場合、df1とdf2は次のようになります。
df1 = df[(df.a != -1) & (df.b != -1)]
df2 = df[(df.a == -1) | (df.b == -1)]