Numpy'de belirtilen indeksleri kullanarak 3B matristen nasıl eleman alabilirim?

Aug 15 2020
  • Bir 3B matrisim var, aşağıdaki örnekte bu bir (5, 4, 2) matris: data_matrix
  • Dizinin her satırının eleman konumunu temsil ettiği başka bir şekil dizilim dizilim (5, 4) var: indx_array

Nasıl elde edebilirim bilmiyorum required_output. Her satırın (1,2) öğelerini şu temelde düzenlemeye çalışıyorum:indx_array

Döngüler için kullanmak istemiyorum!

data_matrix = np.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, 27], [28, 29], [30, 31]], 
    [[32, 33], [34, 35], [36, 37], [38, 39]]
])

indx_array = np.array([[3,2,1,0], [0,1,2,3], [1,0,3,2], [0,3,1,2], [1,2,3,0]])


# I want following result:
required_output = [
    [[6, 7], [4, 5], [2, 3], [0, 1]]
    [[8, 9], [10, 11], [12, 13], [14, 15]]
    [[18, 19], [16, 17], [22, 23], [20, 21]]
    [[24, 25], [30, 31], [26, 27], [28, 29]]
    [[34, 35], [36, 37], [38, 39], [32, 33]]
]

DÜZENLEME: indx_arrayDurumu daha iyi göstermek için güncellendi .

Yanıtlar

3 hpaulj Aug 15 2020 at 21:43
  • Numpy: Endeksleme
    • Numpy: Çok boyutlu dizileri indeksleme
In [637]: data_matrix.shape                                                                          
Out[637]: (5, 4, 2)
In [638]: indx_array.shape                                                                           
Out[638]: (5, 4)

İlk 2 boyutta gelişmiş indekslemeye ihtiyacınız var. İlk boyut dizisinin ikincisi (5,4) ile yayınlanması gerekir. Bunu yapmak için (5,1) yapıyorum arange:

In [639]: data_matrix[np.arange(5)[:,None], indx_array]                                              
Out[639]: 
array([[[ 6,  7],
        [ 4,  5],
        [ 2,  3],
        [ 0,  1]],

       [[ 8,  9],
        [10, 11],
        [12, 13],
        [14, 15]],

       [[18, 19],
        [16, 17],
        [22, 23],
        [20, 21]],

       [[24, 25],
        [30, 31],
        [26, 27],
        [28, 29]],

       [[34, 35],
        [36, 37],
        [38, 39],
        [32, 33]]])

My (5,1) indeksini kabul _xedilenle ((5,4) ravelled olan) karşılaştır:

In [640]: np.arange(5)[:,None]                                                                       
Out[640]: 
array([[0],
       [1],
       [2],
       [3],
       [4]])
In [641]: _x = np.repeat(np.arange(indx_array.shape[0]),indx_array.shape[1])                         
In [643]: _x                                                                                         
Out[643]: array([0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4])

Yayınla _xtekrara ihtiyaç duymaz, (5,4); (5,1) yeterlidir.

Yayın, sanal bir tekrar yapar. Bu, broadcast_tofonksiyonla gösterilebilir :

In [648]: np.broadcast_to(np.arange(5)[:,None],(5,4))                                                
Out[648]: 
array([[0, 0, 0, 0],
       [1, 1, 1, 1],
       [2, 2, 2, 2],
       [3, 3, 3, 3],
       [4, 4, 4, 4]])
In [649]: _.strides                                                                                  
Out[649]: (8, 0)

0Kopyalama yapmadan tekrar eden adımlardır. özellikle pencereleri hareket ettirmek gibi şeyler yaparken as_strideden kullanışlı stride_tricksişlevdir. Genellikle, otomatik yayının işi nasıl yapacağı konusunda çok fazla endişelenmeden yapmasına izin veririz.

4 RichardNemeth Aug 15 2020 at 21:14

Dizin dizisinin biraz aktarılmasıyla yapılabilir.

import numpy as np

_x = np.repeat(np.arange(indx_array.shape[0]),indx_array.shape[1])
_y = indx_array.ravel()

output = data_matrix[_x, _y].reshape(data_matrix.shape)

beklenen uyuşuk diziyle sonuçlanan

array([[[ 6,  7],
        [ 4,  5],
        [ 2,  3],
        [ 0,  1]],

       [[ 8,  9],
        [10, 11],
        [12, 13],
        [14, 15]],

       [[18, 19],
        [16, 17],
        [22, 23],
        [20, 21]],

       [[24, 25],
        [30, 31],
        [26, 27],
        [28, 29]],

       [[34, 35],
        [36, 37],
        [38, 39],
        [32, 33]]])