2015-04-30 19 views
9

Sono bloccato su un piccolo problema nel progetto al momento sto lavorando.Come ottenere una porzione riempita di un array multidimensionale?

Per arrivare dritto al punto, supponiamo di avere un numpy.array bidimensionale - lo chiamerò arr.

Ho bisogno di affettare arr, ma questa sezione deve contenere un riempimento a seconda dell'intervallo selezionato.

Esempio:

arr = numpy.array([ 
    [ 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] 
]) 

In realtà, la risposta numpy s' per arr[3:7, 3:7] è:

array([[19, 20], 
     [24, 25]]) 

Ma ho bisogno di essere imbottito come se arr erano più grandi di quanto realmente sia.

Ecco quello che mi serve come risposta per arr[3:7, 3:7]:

array([[19, 20, 0, 0], 
     [24, 25, 0, 0], 
     [ 0, 0, 0, 0], 
     [ 0, 0, 0, 0]]) 

Questa imbottitura dovrebbe verificarsi anche nel caso di indici negativi. Se la porzione richiesta è più grande di tutta l'immagine, il riempimento deve corrispondere a in tutti i lati, se necessario.

Un altro esempio, indici negativi. Questo è il risultato atteso per arr[-2:2, -1:3]:

array([[ 0, 0, 0, 0], 
     [ 0, 0, 1, 2], 
     [ 0, 0, 6, 7], 
     [ 0, 0, 11, 12]]) 

C'è qualche funzione nativa numpy per questo? In caso negativo, qualche idea su come posso implementarla?

+0

Gli indici negativi hanno già un significato in NumPy, lo stesso di Python in generale, dove -N significa "N elementi di ritorno dalla fine". Sovraccaricarlo per significare qualcosa di diverso in alcuni casi, ma non altri sarebbe una ricetta per una seria confusione. – abarnert

+1

Inoltre, NumPy normalmente restituisce le visualizzazioni anziché le copie quando possibile. Ma ovviamente non è possibile ogni volta che ci potrebbe essere il padding. Quindi, questa non sarebbe una buona idea per l'indicizzazione in generale. – abarnert

+0

Sì, lo so. Ma bene, l'ambito qui è semplicemente una funzione 'numpy' o un metodo interno. –

risposta

3

Circa la prima parte della tua domanda è possibile utilizzare una semplice indicizzazione ed è possibile creare uno zero_like dell'array con numpy.zeros_like quindi assegnare la parte speciale:

>>> new=numpy.zeros_like(arr) 
>>> part=arr[3:7, 3:7] 
>>> i,j=part.shape 
>>> new[:i,:j]=part 
>>> new 
array([[19, 20, 0, 0, 0], 
     [24, 25, 0, 0, 0], 
     [ 0, 0, 0, 0, 0], 
     [ 0, 0, 0, 0, 0], 
     [ 0, 0, 0, 0, 0]]) 

Ma per il secondo caso non è possibile utilizzare un indicizzazione negativa per gli array numpy come questo. indici negativi vengono interpretati come contando dalla fine dell'array quindi se si contano da -2 effettivamente in una matrice 5x5 sono non qualsiasi riga tra -2 e 2, così il risultato sarebbe un array vuoto:

>>> arr[-2:2] 
array([], shape=(0, 5), dtype=int64) 
+1

Risposta interessante, ci provo. So che gli indici negativi sono interpretati come contati dalla fine dell'array, ma ho immaginato che potesse esistere una singola funzione numpy che potesse ignorarlo. Grazie per la risposta, cercherò di cambiare la logica per affrontare questo problema. –

+1

NB Non penso che l'OP abbia voluto np.zeros_like (arr) Penso che volessero np.zeros (xd * yd) .reshape (xd, yd) dove xd e yd sono le differenze nella richiesta cioè 4 = 7- 4, 4 = 2 - -2 e 4 = 3 - -1 come ho tentato di fare sotto. – paddyg

3

Si può fare qualcosa di simile:

print np.lib.pad(arr[3:7,3:7], ((0, 2), (0, 2)), 'constant', constant_values=(0,0)) 



[[19 20 0 0] 
[24 25 0 0] 
[ 0 0 0 0] 
[ 0 0 0 0]] 

Per l'indicizzazione negativo:

print np.lib.pad(arr[ max(0,-1):3 , 0:2 ], ((1, 0), (2, 0)), 'constant', constant_values=(0,0)) 

[[ 0 0 0 0] 
[ 0 0 1 2] 
[ 0 0 6 7] 
[ 0 0 11 12]] 

Controllare here per riferimento

+0

Come ottieni' ((0, 2), (0, 2)) 'e gli altri scenari? – Kasramvd

+0

@Kasra: Può gestire l'imbottitura come vuole. Come per negativo ho aggiunto qualcosa. – George

+0

Questi possono essere semplificati in 'numpy.lib.pad (arr [3: 7, 3: 7], ((0, 2), (0, 2)), 'costante')' e 'numpy.lib.pad (arr [: 3,: 2], ((1, 0), (2, 0)), 'costante') '. – Veedrac

1
import numpy as np 

def convert(inarr, x1, x2, y1, y2): 
    xd = x2 - x1 
    yd = y2 - y1 
    outarr = np.zeros(xd * yd).reshape(xd, yd) 
    x1fr = max(0, x1) 
    x2fr = min(x2, inarr.shape[0]) 
    y1fr = max(0, y1) 
    y2fr = min(y2, inarr.shape[1]) 
    x1to = max(0, xd - x2) 
    x2to = x1to + x2fr - x1fr 
    y1to = max(0, yd - y2) 
    y2to = y1to + y2fr - y1fr 
    outarr[x1to:x2to, y1to:y2to] = inarr[x1fr:x2fr, y1fr:y2fr] 
    return outarr 


arr = np.array([[ 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]]) 

print(convert(arr, -2, 2, -1, 3)) 

bene funziona ma restituisce

[[ 0. 0. 0. 0.] 
[ 0. 0. 0. 0.] 
[ 0. 1. 2. 3.] 
[ 0. 6. 7. 8.]] 

per il suo esempio di indice ve.Puoi giocare per fare ciò che ti aspetti

Problemi correlati