Выберите одно измерение многомерного массива со списком - numpy - PullRequest
0 голосов
/ 21 января 2020

У меня есть 3D-массив формы (800,5,4), например:

arr = array([[35.  , 33.  , 33.  ,  0.15],
       [47.  , 47.  , 44.  ,  0.19],
       [49.  , 56.  , 60.  ,  0.31],
       ...,
       [30.  , 27.  , 25.  ,  0.07],
       [54.  , 49.  , 42.  ,  0.14],
       [33.  , 30.  , 28.  ,  0.22]])

У меня есть 1D-массив индексов для второго измерения (поэтому они варьируются от 0 до 4), например:

indeces = [0,3,2,0,1,1,1,0,...,0,1,2,2,4,3]

Я хочу выбрать элемент idx из второго измерения и получить массив формы (800,4)

Я пробовал следующее, но не смог заставить его работать:

indexed = arr[:,indeces,:]

Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 21 января 2020
In [178]: arr = np.arange(24).reshape(2,3,4)    

Если у меня есть список из 7 предметов:

In [179]: idx = [0,1,1,2,2,0,1]                                                                  
In [180]: arr[:,idx,:]                                                                           
Out[180]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11],
        [ 8,  9, 10, 11],
        [ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [16, 17, 18, 19],
        [20, 21, 22, 23],
        [20, 21, 22, 23],
        [12, 13, 14, 15],
        [16, 17, 18, 19]]])
In [181]: _.shape                                                                                
Out[181]: (2, 7, 4)

Чтобы получить результат (2,4), мы должны выбрать один элемент во 2-м туре для каждой пары из другие измерения.

В общем случае можно создать массив idx a (2,4) и индексировать с измерениями, которые также передают в (2,4):

In [182]: idx = np.array([0,1,1,2,2,0,1,0]).reshape(2,4)                                         
In [183]: arr[np.arange(2)[:,None],idx,np.arange(4)]                                             
Out[183]: 
array([[ 0,  5,  6, 11],
       [20, 13, 18, 15]])
In [184]: _.shape                                                                                
Out[184]: (2, 4)

Или мы можем выбрать скаляр:

In [185]: arr[:,2,:]                                                                             
Out[185]: 
array([[ 8,  9, 10, 11],
       [20, 21, 22, 23]])

@a_guest показал, как это сделать с idx, который соответствует 1-му измерению (и разрезает последнее).

В одну сторону или другой ваш idx должен отобразить или передать с другими измерениями.

0 голосов
/ 21 января 2020

Вам также необходимо выбрать оставшиеся размеры «строка за строкой». То есть вам нужно предоставить индексный массив следующей формы: range(arr.shape[0]). Например:

>>> a = np.arange(27).reshape(3, 3, 3)
>>> i = [0, 1, 2]
>>> a[range(a.shape[0]), i, :]
array([[ 0,  1,  2],
       [12, 13, 14],
       [24, 25, 26]])
>>> a[range(a.shape[0]), i, range(a.shape[2])]
array([ 0, 13, 26])
...