web-dev-qa-db-ja.com

パンダ:データフレームのインデックス作成中の複数の条件-予期しない動作

データフレームの行を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を使用しています。

82

ご覧のとおり、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を使用する習慣を身に付けた方がよいでしょう。

139
DSM

query() を使用できます。つまり:

df_filtered = df.query('a == 4 & b != 2')
31
Pedro Lobito

少し数学論理理論ここ:

"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)]
6
Jake