2016-08-25 17 views
7

これは私に多くの問題をもたらしました。そして、私はパンダ系列のnumpy配列の非互換性に困惑しています。ブール配列でシリーズをマスキングする

x = np.array([1,2,3,4,5,6,7]) 
y = pd.Series([1,2,3,4,5,6,7]) 
delta = np.percentile(x, 50) 
deltamask = x- y > delta 

デルタマスクは、ブール値のpandasシリーズを作成します。あなたは

x[deltamask] 
y[deltamask] 

をすれば

しかし、あなたは、配列がマスクを完全に無視することがわかります。エラーは発生しませんが、長さの異なる2つのオブジェクトになります。

print type(x-y) 
print type(x[deltamask]), len(x[deltamask]) 
print type(y[deltamask]), len(y[deltamask]) 

はさらに困惑が、私はオペレータ<が異なって扱われていることに気づいた:これはエラーで

x[deltamask]*y[deltamask] 

結果などの操作があることを意味します。たとえば、

print type(2*x < x*y) 
print type(2 < x*y) 

は、それぞれpd.seriesとnp.arrayを提供します。

また

、シリーズの

5 < x - y 

結果、スライスになりnumpyの配列に渡されたときに、一連のマスクのブール要素が整数に昇格されているのに対しシリーズは、優先されるようですアレイ。

この理由は何ですか? numpyのよう

+2

'pandas'データ構造は' numpy'配列の上に構築されています。 'Series'は' numpy'配列でうまく***をやっていますが、本当に 'numpy'配列ではありません。また、あなたはどういう意味ですか:_シリーズはマスクを完全に無視します。 'deltamask'は全て' False'なので、 'Series'は値を返すべきではありません。 – Abdou

+0

申し訳ありませんが、私は別の方法の周りを意味しました。シリーズは配列マスクを尊重しませんし、配列はシリーズマスクを尊重しません。 – michel

+0

'シリーズ'は 'numpy配列'マスクを尊重すると思います。もう一度チェック。しかし、細かい配列は 'シリーズ'マスクを取っているようには見えません(実際には面白いです)。しかし、 'x [deltamask.values]'はそのトリックを行います。 – Abdou

答えて

3

ファンシーインデックス

次のように現在、numpyの作品で派手なインデックスを略:

  1. 括弧の間のものがtuple(明示的な括弧付きか否かに関わらず)、ある場合にはタプルの要素は、xのさまざまな次元のインデックスです。たとえば、xが1Dなので、x[(True, True)]x[True, True]の両方がこの場合はIndexError: too many indices for arrayになります。ただし、例外が発生する前に、通知する警告も発生します:VisibleDeprecationWarning: using a boolean instead of an integer will result in an error in the future。括弧間のものが正確ndarrayなく、サブクラスまたは他のアレイ状であり、boolean型を持つ場合

  2. 、これをマスクとして適用されます。 x[deltamask.values]deltamaskがすべてFalseであることから、予想される結果に(空の配列を与えるのはこのためです。

  3. Seriesまたはちょうどlist、または何か他のもののようなサブクラスは、それが変換されているかどうかを括弧の間のものは、任意の配列のような場合にはnp.intp配列(可能であれば)を使用して整数インデックスとして使用すると、x[[False] * 7]またはx[[0] * 7]と同等のものが得られます。この場合、len(deltamask)==7およびx[0]==1となり、結果は[1, 1, 1, 1, 1, 1, 1]になります。

この動作は直観に反している、そしてそれが生成FutureWarning: in the future, boolean array-likes will be handled as a boolean array indexは修正が作品にあることを示しています。私はnumpyに何か変更を加えて/調べるようにこの答えを更新します。

この情報はnumpyのディスカッションhereの私の最初のクエリにセバスチャン・ベルクの応答で見つけることができます。

関係演算子

今度は、比較がどのように機能するかについてのあなたの質問の後半部分に対処しましょう。関係演算子(<><=>=)オブジェクトの一つに対応するメソッドを呼び出すことによって作業が比較されます。 <の場合、これは__lt__です。しかし、x < yの式に対してx.__lt__(y)を呼び出す代わりに、Pythonは実際に比較対象のオブジェクトの型をチェックします。 yは比較を実装xのサブタイプである場合には、Pythonは関係なく、あなたは、元の比較を書いた方法の代わりに、y.__gt__(x)を呼ぶことを好みます。 yxのサブクラスである場合にx.__lt__(y)が呼び出される唯一の方法は、y.__gt__(x)が返された場合、その比較がその方向でサポートされていないことを示すNotImplementedを返します。あなたが5 < x - yを行う際

同様のことが起こります。 ndarrayintのサブクラスではありませんが、Pythonは、実際に定義されて当然のものであり、うまく働く、(x - y).__gt__(5)を呼び出して終わるので、比較はint.__lt__(ndarray)NotImplementedを返します。このすべての

はるかに簡潔な説明がPython docsで見つけることができます。

関連する問題