4

次のような ndarray がある場合:

>>> a = np.arange(27).reshape(3,3,3)
>>> a
array([[[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8]],

       [[ 9, 10, 11],
        [12, 13, 14],
        [15, 16, 17]],

       [[18, 19, 20],
        [21, 22, 23],
        [24, 25, 26]]])

次を使用して、特定の軸に沿って最大値を取得できることを知っていますnp.max(axis=...)

>>> a.max(axis=2)
array([[ 2,  5,  8],
       [11, 14, 17],
       [20, 23, 26]])

または、次の最大値に対応するその軸に沿ったインデックスを取得できます。

>>> indices = a.argmax(axis=2)
>>> indices
array([[2, 2, 2],
       [2, 2, 2],
       [2, 2, 2]])

私の質問 - 配列indicesと配列が与えられた場合、a配列が返す配列を再現する洗練された方法はありa.max(axis=2)ますか?

これはおそらくうまくいくでしょう:

import itertools as it
import numpy as np
def apply_mask(field,indices):
    data = np.empty(indices.shape)

    #It seems highly likely that there is a more numpy-approved way to do this.
    idx = [range(i) for i in indices.shape]
    for idx_tup,zidx in zip(it.product(*idx),indices.flat):
        data[idx_tup] = field[idx_tup+(zidx,)]
    return data

しかし、それはかなりハック/非効率的です。また、「最後の」軸以外の軸でこれを使用することもできません。これを機能させるための numpy 関数 (または魔法の numpy インデックス作成の使用) はありますか? ナイーブa[:,:,a.argmax(axis=2)]は機能しません。

更新

以下も機能するようです(そして少し良いです):

import numpy as np
def apply_mask(field,indices):
    data = np.empty(indices.shape)

    for idx_tup,zidx in np.ndenumerate(indices):
        data[idx_tup] = field[idx_tup+(zidx,)]

    return data

argmax(axis=...)1つの配列のデータに基づいてインデックスを抽出し(通常は を使用)、それらのインデックスを使用して他の(同等の形状の)配列の束からデータを引き出したいため、これを行いたいと思います。私はこれを達成するための別の方法を受け入れています (たとえば、ブール値のマスクされた配列を使用します)。ただし、これらの「インデックス」配列を使用して得られる「安全性」が気に入っています。これにより、3D フィールドを通る 2D の「スライス」のように見える新しい配列を作成するための適切な数の要素があることが保証されます。

4

2 に答える 2

3

これがあなたが望むことをするいくつかの魔法のゴツゴツした索引付けです、しかし残念ながらそれはかなり読めません。

def apply_mask(a, indices, axis):
    magic_index = [np.arange(i) for i in indices.shape]
    magic_index = np.ix_(*magic_index)
    magic_index = magic_index[:axis] + (indices,) + magic_index[axis:]
    return a[magic_index]

または同様に読めない:

def apply_mask(a, indices, axis):
    magic_index = np.ogrid[tuple(slice(i) for i in indices.shape)]
    magic_index.insert(axis, indices)
    return a[magic_index]
于 2013-03-18T04:33:10.613 に答える
-1

index_at()は完全なインデックスを作成するために使用します:

import numpy as np

def index_at(idx, shape, axis=-1):
    if axis<0:
        axis += len(shape)
    shape = shape[:axis] + shape[axis+1:]
    index = list(np.ix_(*[np.arange(n) for n in shape]))
    index.insert(axis, idx)
    return tuple(index)

a = np.random.randint(0, 10, (3, 4, 5))

axis = 1
idx = np.argmax(a, axis=axis)
print a[index_at(idx, a.shape, axis=axis)]
print np.max(a, axis=axis)
于 2013-03-18T06:01:10.253 に答える