or
条件で私の結果データフレームをフィルタリングすることに問題があります。私の結果df
は、0.25より上で-0.25より下のすべての列var
値を抽出することを望みます。
以下のこの論理は私にあいまいな真理値を与えます、しかし私がこのフィルタリングを2つの別々の操作に分割するときそれは働きます。ここで何が起きてるの?推奨されているa.empty(), a.bool(), a.item(),a.any() or a.all()
をどこで使用するかわからない。
result = result[(result['var']>0.25) or (result['var']<-0.25)]
ブール論理の場合は、&
および|
を使用します。
np.random.seed(0)
df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC'))
>>> df
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
2 0.950088 -0.151357 -0.103219
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.443863
>>> df.loc[(df.C > 0.25) | (df.C < -0.25)]
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.443863
何が起こっているのかを見るために、比較ごとにブール値の列を取得します。
df.C > 0.25
0 True
1 False
2 False
3 True
4 True
Name: C, dtype: bool
複数の基準がある場合は、複数の列が返されます。これが、結合ロジックがあいまいな理由です。 and
またはor
を使用すると各列が別々に処理されるため、まずその列を単一のブール値に減らす必要があります。たとえば、各列のいずれかの値またはすべての値がTrueかどうかを確認します。
# Any value in either column is True?
(df.C > 0.25).any() or (df.C < -0.25).any()
True
# All values in either column is True?
(df.C > 0.25).all() or (df.C < -0.25).all()
False
同じことを達成するための複雑な方法の1つは、これらすべての列をまとめて圧縮し、適切なロジックを実行することです。
>>> df[[any([a, b]) for a, b in Zip(df.C > 0.25, df.C < -0.25)]]
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.443863
詳細については、ドキュメントの ブールインデックス を参照してください。
あるいは、オペレータモジュールを使用することもできます。より詳細な情報はここにあります Pythonのドキュメント
import operator
import numpy as np
import pandas as pd
np.random.seed(0)
df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC'))
df.loc[operator.or_(df.C > 0.25, df.C < -0.25)]
A B C
0 1.764052 0.400157 0.978738
1 2.240893 1.867558 -0.977278
3 0.410599 0.144044 1.454274
4 0.761038 0.121675 0.4438
この優れた答え は何が起こっているのか非常によく説明し、解決策を提供します。私は似たような場合にふさわしいかもしれない別の解決策を加えたいと思います: query
メソッドを使うこと:
result = result.query("(var > 0.25) or (var < -0.25)")
http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-query も参照してください。
(私が現在取り組んでいるデータフレームを使ったいくつかのテストでは、この方法は一連のブール値に対してビット演算子を使うよりも少し遅いことが示唆されています:2 ms対870 µs)
警告の断片 :これが簡単ではない状況の少なくとも1つは、列名が偶然python式になっている場合です。 WT_38hph_IP_2
、WT_38hph_input_2
、log2(WT_38hph_IP_2/WT_38hph_input_2)
という名前の列があり、次のクエリを実行したいと思いました。"(log2(WT_38hph_IP_2/WT_38hph_input_2) > 1) and (WT_38hph_IP_2 > 20)"
次のような例外のカスケードを取得しました。
KeyError: 'log2'
UndefinedVariableError: name 'log2' is not defined
ValueError: "log2" is not a supported function
これは、クエリパーサーが3列目の名前で式を識別するのではなく、最初の2列から何かを作成しようとしていたために起こったと思います。
可能な回避策は提案されています ここ 。