web-dev-qa-db-ja.com

タプルのリストを使用したnumpy配列のインデックス作成

タプルインデックスのリストを使用してndarrayにインデックスを付けることができないのはなぜですか?

idx = [(x1, y1), ... (xn, yn)]
X[idx]

代わりに、私は扱いにくい何かをしなければなりません

idx2 = numpy.array(idx)
X[idx2[:, 0], idx2[:, 1]] # or more generally:
X[Tuple(numpy.vsplit(idx2.T, 1)[0])]

よりシンプルでよりPython的な方法はありますか?

21
Emre

タプルのリストを使用できますが、規則は希望のものとは異なります。 numpyには、行インデックスのリストと、それに続く列値のリストが必要です。明らかに、(x、y)ペアのリストを指定する必要があります。

http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html#integer-array-indexing ドキュメントの関連セクションは「整数配列のインデックス」です。


以下は、2次元配列で3つのポイントを探す例です。 (2dの2ポイントは混乱する可能性があります):

_In [223]: idx
Out[223]: [(0, 1, 1), (2, 3, 0)]
In [224]: X[idx]
Out[224]: array([2, 7, 4])
_

インデックスのxyペアのスタイルを使用する:

_In [230]: idx1 = [(0,2),(1,3),(1,0)]
In [231]: [X[i] for i in idx1]
Out[231]: [2, 7, 4]

In [240]: X[Tuple(np.array(idx1).T)]
Out[240]: array([2, 7, 4])
_

X[Tuple(Zip(*idx1))]は、変換を行う別の方法です。 Tuple()はPython2ではオプションです。 Zip(*...)はPythonイディオムで、リストのリストのネストを逆にします。

あなたは正しい方向に進んでいます:

_In [242]: idx2=np.array(idx1)
In [243]: X[idx2[:,0], idx2[:,1]]
Out[243]: array([2, 7, 4])
_

私のTuple()は、もう少しコンパクトです(必ずしもより「Pythonic」ではありません)。 numpy規則を考えると、何らかの変換が必要です。

(n次元とm点で何が機能するかを確認する必要がありますか?)

31
hpaulj

要素を取得するために行列に直接渡すことができるnumpy配列のタプルを使用します

Index = Tuple(np.array(list(Zip(*index_Tuple))))
new_array = list(prev_array[index])
1
Aarif1430