パンダシリーズの要素ごとの論理NOTを取得するにはどうすればよいですか?


229

Seriesブール値を含むpandas オブジェクトがあります。NOT各値の論理値を含むシリーズを取得するにはどうすればよいですか?

たとえば、以下を含むシリーズを考えてみましょう。

True
True
True
False

私が入手したいシリーズには以下が含まれます:

False
False
False
True

これはかなりシンプルなはずですが、どうやら私はmojo =(


1
データが含まれていないことが重要であるobject、仕事に以下の回答の型を使用ので:~ df.astype('bool')
LearnOPhile

この投稿では、すべての論理演算子について書きました。投稿には代替案も含まれています。
cs95

回答:


260

ブールシリーズを反転するには、次を使用します~s

In [7]: s = pd.Series([True, True, False, True])

In [8]: ~s
Out[8]: 
0    False
1    False
2     True
3    False
dtype: bool

Python2.7、NumPy 1.8.0、Pandas 0.13.1を使用:

In [119]: s = pd.Series([True, True, False, True]*10000)

In [10]:  %timeit np.invert(s)
10000 loops, best of 3: 91.8 µs per loop

In [11]: %timeit ~s
10000 loops, best of 3: 73.5 µs per loop

In [12]: %timeit (-s)
10000 loops, best of 3: 73.5 µs per loop

Pandas 0.13.0以降、Seriesはのサブクラスではなくなりましたnumpy.ndarray。それらはのサブクラスになりましたpd.NDFrame。これはnp.invert(s)~sやほど速くない理由と関係があるかもしれません-s

警告:timeit結果は、ハードウェア、コンパイラ、OS、Python、NumPy、Pandasのバージョンなど、多くの要因によって異なる場合があります。


正式に指摘した。チルドとの違いは何-ですか?
blz 2013

奇妙に、私は実際にテストしtilde、それがドキュメントに記載されたように、それは同じように実行されませんでしたnp.invert:S
ルート

@blz:numpyの1.6.2のパフォーマンスを実行している、私のUbuntuマシン上に少なくともnp.invert(s)~s-sすべて同じです。
unutbu 2013

@root:timeitの結果にこのような大きな差異がある理由はわかりませんが、確かに発生する可能性があります。使用しているOSとNumPyのバージョンは何ですか?
unutbu

Ubuntu np.bitwise_not(s)でも同じですが、NumPy 1.7.0 ...(を使用するとnp.inverse)と同じように動作します。
ルート

32

@unutbuの答えはその場にあり、マスクを「オブジェクト」ではなくdtype boolにする必要があるという警告を追加したかっただけです。つまり、あなたのマスクはしていないことができ、これまで任意のナンの持っていました。ここを参照してください -マスクがナンフリーになっても、「オブジェクト」タイプのままになります。

「オブジェクト」シリーズの逆はエラーをスローしませんが、期待どおりに機能しない整数のガベージマスクを取得します。

In[1]: df = pd.DataFrame({'A':[True, False, np.nan], 'B':[True, False, True]})
In[2]: df.dropna(inplace=True)
In[3]: df['A']
Out[3]:
0    True
1   False
Name: A, dtype object
In[4]: ~df['A']
Out[4]:
0   -2
0   -1
Name: A, dtype object

これについて同僚と話した後、私は説明をします:パンダがビット演算子に戻っているようです:

In [1]: ~True
Out[1]: -2

@geherが言うように、〜で反転する前に、それをastypeでブールに変換できます

~df['A'].astype(bool)
0    False
1     True
Name: A, dtype: bool
(~df['A']).astype(bool)
0    True
1    True
Name: A, dtype: bool

あなたの例では、出力intマスクはあなたが望むブールシリーズに変換することができます。.astype(bool)例えば~df['A'].astype(bool)
geher

vsのastype(bool)前に起こっているため、これは機能しています~ ~df['A'].astype(bool)(~df['A']).astype(bool)
JSharm

16

私はそれを試してみるだけです:

In [9]: s = Series([True, True, True, False])

In [10]: s
Out[10]: 
0     True
1     True
2     True
3    False

In [11]: -s
Out[11]: 
0    False
1    False
2    False
3     True

文字通り-!以外のすべての演算子を試しました。これは次回のために覚えておきます。
blz 2013

6

あなたも使うことができますnumpy.invert

In [1]: import numpy as np

In [2]: import pandas as pd

In [3]: s = pd.Series([True, True, False, True])

In [4]: np.invert(s)
Out[4]: 
0    False
1    False
2     True
3    False

編集:パフォーマンスの違いはUbuntu 12.04、Python 2.7、NumPy 1.7.0で表示されますが、NumPy 1.6.2を使用しても存在しないようです。

In [5]: %timeit (-s)
10000 loops, best of 3: 26.8 us per loop

In [6]: %timeit np.invert(s)
100000 loops, best of 3: 7.85 us per loop

In [7]: %timeit ~s
10000 loops, best of 3: 27.3 us per loop

別のプラットフォームでは正しくない場合があります。Win 7、python 3.6.3 numpy 1.13.3、pandas 0.20.3、(-s)が最速、(〜s)が2番目、np.invert(s)が最も遅い
gaozhidf

0

NumPyは、入力をブール値にキャストするため低速です(したがって、Noneと0はFalseになり、その他はすべてTrueになります)。

import pandas as pd
import numpy as np
s = pd.Series([True, None, False, True])
np.logical_not(s)

あなたにあげる

0    False
1     True
2     True
3    False
dtype: object

一方、〜sはクラッシュします。ほとんどの場合、チルダはNumPyよりも安全な選択です。

パンダ0.25、NumPy 1.17

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.