Numpyの高度なチュートリアルnp.whereおよびnp.piecewise



Numpy Advanced Tutorial Np





「BraveAI」公開番号、より多くのpython学習、データ分析、機械学習、共有するディープラーニングのオリジナル記事、およびダウンロードするより多くの電子リソース、チュートリアル、データセットへようこそ。ブレイブAI、人工知能AIに焦点を当てた公開番号。

================================================== ================================



numpyのチュートリアルについては、すでに多くの記事を要約しており、numpyの高度なアプリケーションselect andchooseについても書いています。学生が私のブログまたはブログのWeChatパブリックプラットフォームを見る必要があります。機能は特に明確です。今日の記事では、np.whereとnp.piecewise、およびマスク配列に焦点を当てています。

まず、np.where()関数の詳細

名前が示すように、この関数はルックアップ関数に似ています。ここで、は意味があり、前の選択と選択は選択の意味であり、多少似ています。実際、where関数は「find」のより高度な機能を提供します。

1、where関数の定義



numpy.where調子 [、 バツY ])

だけなら 調子 が与えられたら、condition.nonzero()を返します。

パラメーター:

調子 :array_like、bool

Trueの場合、yield バツ 、それ以外の場合は Y

x、y :array_like、オプション

選択する値。 バツY そして 調子 何らかの形に放送可能である必要があります。

戻り値:

アウト :ndarrayまたはndarrayのタプル

両方の場合 バツ そして Y が指定されている場合、出力配列には次の要素が含まれます。 バツ どこ 調子 はTrueであり、 Y 他の場所。

だけなら 調子 が与えられたら、タプルcondition.nonzero()を返します。 調子 Trueです。

説明:

この関数は、必要なパラメーター条件を受け入れることができます。パラメーターは配列型である必要がありますが、要素はtrueまたはfalseであることに注意してください。

x、yはオプションのパラメータです。条件がtrueの場合はxを返し、条件がfalseの場合はyを返します。条件、x、yは同じ形状に「ブロードキャスト」できる必要があることに注意してください。

結果を返します。配列が返されるか、要素が配列であるタプルタプルが返されます。条件が1つしかない場合は、配列を含むタプルが返されます。パラメータが3つある場合は、配列が返されます。後で詳しく説明します。

総括する: Numpyは、実際には高度にカプセル化された条件付き操作です。 numpy.where関数は、条件がyの場合は3項式xのベクトル化されたバージョンであると言えます。ブール配列と2つの値の配列を定義します。返される結果は、実際には、検索される要素の「位置」または「インデックス」または「座標」です。位置、インデックス、および座標は同等です。素人の用語では、返される値は要素がどこにあるかです。

2、パラメータ条件が1つしかない実際のケース

(1)条件は一次元です

a = np.array([2,4,6,8,10]) A_where=np.where(a > 5) # Returns the index, a>5 gets the array. print(a_where) Print(a[np.where(a > 5)]) # is equivalent to a[a>5], boolean index b=np.array([False,True,False,True,False]) print(np.where(b))

印刷結果は次のとおりです。

(array([2、3、4]、dtype = int64)、)#返された2、3、4は、要素が5(True)より大きい要素のインデックス位置、つまり3番目、4番目、および5番目の要素、配列の形式で返します
[6 8 10]
(array([1、3]、dtype = int64)、)#Trueの要素内の要素、つまり2番目と4番目の要素に対応する位置インデックスを返します。配列の形式で返します。

(2)状態は2次元です

a=np.array([[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6, 7,8]]) #2D array a_where=np.where(a>3) print(a_where) print(a[a_where])

操作の結果は次のとおりです。

(array([0、0、1、1、1、2、2、2、2、3、3、3、3、3]、dtype = int64)、array([3、4、2、3、4 、1、2、3、4、0、1、2、3、4]、dtype = int64))
[4 5 4 5 6 4 5 6 7 4 5 6 7 8]

最初の戻りの結果については、タプルタプルを返すことがわかります。タプルの最初の要素は、条件を満たす要素の行インデックスから値が派生する配列です。2つのゼロ行、3つの1行、4つの2行、5つの3行祖先の2番目の要素も配列であり、その値は、条件を満たす要素の列インデックスから派生します。

例を見てください

b=np.where([[0, 3,2], [0,4, 0]]) print(b)

結果は次のとおりです。

(array([0、0、1]、dtype = int64)、array([1、2、1]、dtype = int64))

#はまだタプルタプルであり、最初の要素は行から派生した配列であり、2番目の要素も列から派生した配列です。 whereパラメータはb> 1、b> 2、その他のブール式ではなくbであるため、これは削除条件ではないことに注意してください。何が起こっているのでしょうか。実際、それはさらに処理されます。 0を偽、0より大きいすべてを真と考えてください。これは次の結果と完全に同等です。

c=np.array([[False,True,True],[False,True,False]]) print(np.where(c))

出力は次のとおりです。(array([0、0、1]、dtype = int64)、array([1、2、1]、dtype = int64))#は上記とまったく同じです

(3)条件は多次元です-3Dを例にとると

a=[ [ [1,2,3],[2,3,4],[3,4,5] ], [ [0,1,2],[1,2,3],[2,3,4] ] ] a=np.array(a) Print(a.shape) #shape is (2,3,3) a_where=np.where(a>3) print(a_where)

操作の結果は次のとおりです。

(array([0、0、0、1]、dtype = int64)、

array([1、2、2、2]、dtype = int64)、

array([2、1、2、2]、dtype = int64))

上記と同じように、戻り値はタプル、最初の要素は配列型、最初の次元からのインデックスは条件を満たす、2番目の要素は配列型、2番目の次元からのインデックスは条件を満たし、3番目のelementは配列型であり、3次元が条件を満たすインデックスから派生します。

総括する: 上記の説明では、whereの役割は、配列の条件を満たす要素のインデックス(True)を返すことであり、戻り値はタプル型です。タプルの各要素は配列型であり、配列の値は特定の緯度に対応します。のインデックス。

パラメータ条件が与えられた場合、np.where(condition)とcondition.nonzero()は完全に同等です。

3. 3つのパラメーター条件、x、yを使用した実際のケース

a = np.arange(10) a_where=np.where(a,1,-1) print(a_where) a_where_1=np.where(a > 5,1,-1) print(a_where_1) b=np.where([[True,False], [True,True]], #first parameter [[1,2], [3,4]], #second parameter [[9,8], [7,6]] #third parameter ) print(b)

操作の結果は次のとおりです。

[-1 1 1 1 1 1 1 1 1 1]
[-1 -1 -1 -1 -1 -1 1 1 1 1]
[[1 8]
[3.4]]

最初の結果では、最初の結果のみが0、つまりfalseであるため、-1に置き換えられ、後者は0より大きい、つまりtrueであるため、1に置き換えられます。

2番目の結果では、最初の6つはすべて偽であるため、-1に置き換え、次の4つは真になり、次に1に置き換えます。

3番目の結果については、

最初のTrueに対応するインデックス位置は(0,0)であり、Trueは2番目のパラメーターにあり、(0,0)は要素1に対応します。

2番目のfalseに対応するインデックス位置は(0、1)、falseは3番目のパラメーターにあり、(0、1)は要素8に対応します。

3番目のTrueに対応するインデックス位置は(1、0)、trueは2番目のパラメーターにあり、(0、0)は要素3に対応します。

4番目のTrueに対応するインデックス位置は(1、1)、trueは2番目のパラメーターにあり、(0、0)は要素4に対応します。

概要:3つのパラメーターを使用する場合、条件x、yは同じ次元であるか、同じ形状にブロードキャストできる必要があることに注意してください。そうでない場合、エラーが報告され、返される結果は元のリストと同じです。状態寸法と形状。

要約:上記の説明を通じて、本質的に選択操作であるnp.where関数の能力をすでに学習しましたが、条件付き操作を自分で作成する場合は、if-elseやlist式などのステートメントを使用します。これは非効率的です。したがって、np.whereを使用することをお勧めします。

次に、np.piecewise関数の詳細

Np.piecewiseも前と同じで、select、choose、advancedアプリケーションに属し、関数の実装も同様です。つまり、関連する条件に従って、スクリーニングを行い、関連する操作を実行します。さまざまな条件の要素であるこのオペレーションは、ソースと関数、ラムダ式などであり、新しい結果を取得できます。

1、np。区分的定義

numpy.piecewiseバツcondlistfunclist* args** kw )。

区分的に定義された関数を評価します。

一連の条件と対応する関数が与えられた場合、その条件が真である場合は常に、入力データの各関数を評価します。

パラメーター:

バツ :ndarrayまたはスカラー

入力ドメイン。

condlist :bool配列またはboolスカラーのリスト

各ブール配列は、の関数に対応します。 funclist 。どこでも condlist [i] 本当です、 funclist [i](x) 出力値として使用されます。

の各ブール配列 condlist の一部を選択します バツ 、したがって、と同じ形状である必要があります バツ

の長さ condlist のそれに対応する必要があります funclist 。追加の関数が1つ指定されている場合、つまりif len(funclist) == len(condlist) + 1の場合、その追加の関数がデフォルト値であり、すべての条件がfalseの場合に使用されます。

funclist :呼び出し可能オブジェクト、f(x、* args、** kw)、またはスカラーのリスト

各機能は評価されます バツ 対応する条件がTrueの場合。入力として1d配列を取り、出力として1d配列またはスカラー値を与える必要があります。呼び出し可能の代わりにスカラーが提供される場合、定数関数(lambda x: scalar)が想定されます。

引数 :タプル、オプション

に与えられたさらなる議論 piecewise 実行時に関数に渡されます。つまり、piecewise(..., ..., 1, 'a')が呼び出された場合、各関数はf(x, 1, 'a')として呼び出されます。

kw :dict、オプション

呼び出しに使用されるキーワード引数 piecewise 実行時に関数に渡されます。つまり、呼び出された場合piecewise(..., ..., alpha=1)の場合、各関数はf(x, alpha=1)として呼び出されます。

戻り値:

アウト :ndarray

出力はxと同じ形状と型であり、で関数を呼び出すことによって検出されます。 funclist の適切な部分に バツ 、のブール配列で定義されているように condlist 。条件の対象とならない部分のデフォルト値は0です。

パラメータ1x:操作対象を示します

パラメーター2:condlist。満たすべき条件のリストを示します。これは、複数の条件のリストにすることができます。

パラメーター3:funclist、実行された操作のリスト、パラメーター2はパラメーター3に対応し、パラメーター2がtrueの場合、対応する操作関数が実行されます。

戻り値:元の操作オブジェクトxとまったく同じ寸法と形状の配列オブジェクトを返します。

2、np。区分的実際のケース

(1)ケース1

x = np.arange(0,10) print(x) xx=np.piecewise(x, [x = 6], [-1, 1]) print(xx)

操作の結果は次のとおりです。

[0 1 2 3 4 5 6 7 8 9]
[-1 -1 -1 -1 0 0 1 1 1 1]

つまり、要素を-1の4未満に置き換え、1以上に置き換え、残りを0に置き換えます。実際、ここでの置き換えとパディングは関数ですが、ここでの関数は単純で失礼であり、同じ番号に置き換えられました。実際、上記のコードは次のコードとまったく同じです。

x = np.arange(0,10) def func1(y): return -1 def func2(y): return 1 xxx=np.piecewise(x, [x = 6], [func1, func2]) print(xxx)

操作の結果は次のとおりです。

[-1 -1 -1 -1 0 0 1 1 1 1]#

(2)ケース2-関連する運用機能の定義

x = np.arange(0,10) # def func2(y): return 1ef func1(y): return y**2 # Multiply by 100 def func2(y): return y*100 xxx=np.piecewise(x, [x = 6], [func1, func2]) print(xxx)

操作の結果は次のとおりです。

[0 1 4 9 0 0600700800900]

(3)ケース3-ラムダ式を使用する

x = np.arange(0,10) xxxx=np.piecewise(x, [x = 6], [lambda x:x**2, lambda x:x*100]) print(xxxx)

操作の結果は次のとおりです。

[0 1 4 9 0 0600700800900]

総括する: 区分的処理は迅速かつ簡単であり、ループや条件文を作成するよりもはるかに効率的です。もっと使うことをお勧めします。