2015-11-17 13 views
15

私はnumpy.where(condition[, x, y])の機能を試しています。返す、唯一の条件が与えられている場合numpy.where(条件)の出力は配列ではなく、配列のタプルです:なぜですか?

:私はあなたが入力として一つだけの配列を与えた場合、それは、配列が非ゼロ(すなわち「真」)であるインデックスを返す必要があることを学ぶnumpy documentation,から
tuple condition.nonzero()、 インデックスは、条件が真であるインデックスです。

しかし、それをしようとした場合、それは私の最初のインデックスの指名手配リストであり、第二がnull要素である二つの要素のタプル、返す:質問そう

>>> import numpy as np 
>>> array = np.array([1,2,3,4,5,6,7,8,9]) 
>>> np.where(array>4) 
(array([4, 5, 6, 7, 8]),) # notice the comma before the last parenthesis 

をです:なぜですか?この行動の目的は何ですか?どのような状況でこれは役に立ちますか? 実際、インデックスの必要なリストを取得するには、np.where(array>4)[0]のようにインデックスを追加する必要があります。これは... "醜い"と思われます。


補遺

私はそれが実際にただ一つの要素のタプルであることを(いくつかの回答から)理解しています。それでも私はこのように出力を与える理由を理解していません。これは理想的ではない方法を説明するために、(最初の場所で私の質問をやる気)以下のエラーを考慮してください。あなたは、インデックスの実際の配列にアクセスするには、いくつかのインデックス作成を行う必要があり

>>> import numpy as np 
>>> array = np.array([1,2,3,4,5,6,7,8,9]) 
>>> pippo = np.where(array>4) 
>>> pippo + 1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: can only concatenate tuple (not "int") to tuple 

よう:

>>> pippo[0] + 1 
array([5, 6, 7, 8, 9]) 
+0

「np.argwhere」についてはどうですか? – Divakar

+3

あなたが望むのは、 'a.ravel()を実行する' np.flatnonzero'です。nonzero()[0] '。 – hpaulj

答えて

21

Python (1)では、ちょうど1を意味します。 ()は、人の読みやすいようにグループ番号と式に自由に追加できます(例:(1+3)*3 v (1+3,)*3)。したがって、1要素タプルを表すには(1,)を使用します(また、それを使用する必要もあります)。

したがって

(array([4, 5, 6, 7, 8]),) 

は、1つの要素のタプル、配列されている要素です。

whereを2次元配列に適用した場合、結果は2要素タプルになります。

whereの結果は、インデックス付けスロットに直接差し込むことができるようなものです。=============

In [278]: a=np.array([1,2,3,4,5,6,7,8,9]) 
In [279]: np.where(a>4) 
Out[279]: (array([4, 5, 6, 7, 8], dtype=int32),) # tuple 

In [280]: a[np.where(a>4)] 
Out[280]: array([5, 6, 7, 8, 9]) 

In [281]: I=np.where(a>4) 
In [282]: I 
Out[282]: (array([4, 5, 6, 7, 8], dtype=int32),) 
In [283]: a[I] 
Out[283]: array([5, 6, 7, 8, 9]) 

In [286]: i, = np.where(a>4) # note the , on LHS 
In [287]: i 
Out[287]: array([4, 5, 6, 7, 8], dtype=int32) # not tuple 
In [288]: a[i] 
Out[288]: array([5, 6, 7, 8, 9]) 
In [289]: a[(i,)] 
Out[289]: array([5, 6, 7, 8, 9]) 

a[where(a>0)] 
a[a>0] 

I,J = where(a>0) # a is 2d 
a[I,J] 
a[(I,J)] 

またはあなたの例の場合と同じもの

を返す必要があります=========

np.flatnonzeroは、入力配列の大きさに関係なく、1つの配列だけを返す正しい方法。

In [299]: np.flatnonzero(a>4) 
Out[299]: array([4, 5, 6, 7, 8], dtype=int32) 
In [300]: np.flatnonzero(a>4)+10 
Out[300]: array([14, 15, 16, 17, 18], dtype=int32) 

イッツDOCは言う:

これはa.ravel()と等価であるゼロ以外の()[0]文字通り機能が何をするかで実際に

平滑化すると、aは複数の次元で何をすべきかという問題を取り除きます。そして、それはタプルから応答を取り出し、あなたに平易な配列を与えます。平坦化を行うと、1次元配列の特殊なケースを作成する必要はありません。

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

@Divakarがnp.argwhereことを示唆している:

np.transpose(np.where(a>4))を行い
In [303]: np.argwhere(a>4) 
Out[303]: 
array([[4], 
     [5], 
     [6], 
     [7], 
     [8]], dtype=int32) 

それとも、列ベクトルを好きではない場合、あなたは今、それがある以外、再び

In [307]: np.argwhere(a>4).T 
Out[307]: array([[4, 5, 6, 7, 8]], dtype=int32) 

それをトランスポーズでき1×nアレイ。

私達はちょうど同様arraywhereに包まれている可能性:whereタプル([0]i,=transposearray、など)からの配列を取る方法の

In [311]: np.array(np.where(a>4)) 
Out[311]: array([[4, 5, 6, 7, 8]], dtype=int32) 

たくさん。

+0

こんにちは@hpaulj、あなたの答えに感謝します。私はそれが1要素のタプルであることを理解しています。それでも、実際の配列にアクセスするには索引付けが必要です。理由を理解できません。つまり、そのように出力する理由... 編集した質問の補遺を参照してください。 – Fabio

+1

すべてのアレイで一貫性が維持されることが目標です。 'np.flatnonzero'は、タプルの代わりに配列を返す正しい方法を示しています。 – hpaulj

5

短い回答:np.whereは、アレイの寸法に関係なく一貫した出力を持つように設計されています。

2次元配列には2つのインデックスがあるため、np.whereの結果は、関連するインデックスを含む長さ2のタプルです。これは、3次元の場合は長さ3タプル、4次元の場合は長さ4タプル、N次元の場合は長さNタプルに一般化されます。このルールによって、1次元では結果が長さ1のタプルであることが明らかです。

0

np.asarray機能を使用してください。あなたの場合:

>>> import numpy as np 
>>> array = np.array([1,2,3,4,5,6,7,8,9]) 
>>> pippo = np.asarray(np.where(array>4)) 
>>> pippo + 1 
array([[5, 6, 7, 8, 9]]) 
+0

'np.asarray()'が 'np.array()'の代わりに使われるのはなぜですか? – mikey

関連する問題