web-dev-qa-db-ja.com

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

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

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

True
True
True
False

取得したいシリーズには次のものが含まれます。

False
False
False
True

これは合理的にシンプルであるように思えますが、どうやら自分のmojo =(

171
blz

ブールシリーズを反転するには、 ~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以降、シリーズはnumpy.ndarrayのサブクラスではなくなりました。それらは現在pd.NDFrameのサブクラスです。これは、np.invert(s)~s-sほど速くない理由と関係があるかもしれません。

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

194
unutbu

@unutbuの答えはスポットオンであり、マスクが「オブジェクト」ではなくdtype boolである必要があるという警告を追加したかっただけです。つまり、マスクにeverを含めることはできません。 here を参照してください-マスクが現在nan-freeであっても、「オブジェクト」タイプのままです。

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

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

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

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

ちょっと試してみましょう:

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
11
herrfz

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
5
root