2016-07-04 31 views
9

Qual è il modo più poderoso per riempire un array con zeri alla fine?Zero pad numpy array

def pad(A, length): 
    ... 

A = np.array([1,2,3,4,5]) 
pad(A, 8) # expected : [1,2,3,4,5,0,0,0] 

Nel mio caso reale utilizzo, infatti voglio pad una matrice al più vicino multiplo di 1024. Es: 1342 => 2048, 3000 => 3072

risposta

12

numpy.pad con modalità constant fa quello che ti serve, dove possiamo passare una tupla come secondo argomento per dire quanti zeri pad su ogni dimensione, un (2, 3) per esempio sarà pad zeri sul lato sinistro e zeri sul lato destro:

Dato A come:

A = np.array([1,2,3,4,5]) 

np.pad(A, (2, 3), 'constant') 
# array([0, 0, 1, 2, 3, 4, 5, 0, 0, 0]) 

E 'anche possibile pad array un 2D NumPy facendo passare una tupla come larghezza imbottitura, che tak es il formato di ((top, bottom), (left, right)):

A = np.array([[1,2],[3,4]]) 

np.pad(A, ((1,2),(2,1)), 'constant') 

#array([[0, 0, 0, 0, 0],   # 1 zero padded to the top 
#  [0, 0, 1, 2, 0],   # 2 zeros padded to the bottom 
#  [0, 0, 3, 4, 0],   # 2 zeros padded to the left 
#  [0, 0, 0, 0, 0],   # 1 zero padded to the right 
#  [0, 0, 0, 0, 0]]) 

Per il vostro caso, è necessario specificare il lato sinistro pari a zero e il tappetino lato destro calcolato da una divisione modulare:

B = np.pad(A, (0, 1024 - len(A)%1024), 'constant') 
B 
# array([1, 2, 3, ..., 0, 0, 0]) 
len(B) 
# 1024 

per una più grande A:

A = np.ones(3000) 
B = np.pad(A, (0, 1024 - len(A)%1024), 'constant') 
B 
# array([ 1., 1., 1., ..., 0., 0., 0.]) 

len(B) 
# 3072 
+0

Grazie! Funziona se la lunghezza originale è 3000? (quindi la lunghezza imbottita dovrebbe essere 3072) – Basj

+0

Dovrebbe, poiché la lunghezza corretta del padding qui è la differenza tra '1024' e il resto modulare di' len (A) 'diviso per' 1024'. Dovrebbe essere facile da testare. – Psidom

2

Questo dovrebbe funzionare:

def pad(A, length): 
    arr = np.zeros(length) 
    arr[:len(A)] = A 
    return arr 

È potrebbe essere in grado di ottenere prestazioni leggermente migliori se si inizializza una matrice vuota (np.empty(length)) e quindi compilare A e tH e zeros separatamente, ma dubito che gli aumenti di velocità varrebbero la complessità aggiuntiva del codice nella maggior parte dei casi.

per ottenere il valore per riempire fino a, credo che si sarebbe probabilmente basta usare qualcosa come divmod:

n, remainder = divmod(len(A), 1024) 
n += bool(remainder) 

Fondamentalmente, questo calcola solo quante volte 1024 divide la lunghezza del vostro array (e cos'è il resto di quella divisione). Se non c'è resto, allora vuoi solo gli elementi n * 1024. Se c'è un resto, allora vuoi (n + 1) * 1024.

tutto insieme:

def pad1024(A): 
    n, remainder = divmod(len(A), 1024) 
    n += bool(remainder) 
    arr = np.zeros(n * 1024) 
    arr[:len(A)] = A 
    return arr   
+0

Grazie! Qualche idea per il riempimento automatico per rendere la lunghezza un multiplo di 1024? Sto scrivendo qualcosa ma è altamente non pythonic;) – Basj

+0

@Basj - Certo, controlla il mio aggiornamento. Non ho provato nulla, ma penso che dovrebbe funzionare ... – mgilson

+0

Questo è ciò che 'pad' fa, ma con un sacco di campane-n-fischietti (fronte, retro, diversi assi, altre modalità di riempimento). – hpaulj

1

Si potrebbe anche usare numpy.pad:

>>> A = np.array([1,2,3,4,5]) 
>>> npad = 8 - len(A) 
>>> np.pad(A, pad_width=npad, mode='constant', constant_values=0)[npad:] 
array([1, 2, 3, 4, 5, 0, 0, 0]) 

E in una funzione:

def pad(A, npads): 
    _npads = npads - len(A) 
    return np.pad(A, pad_width=_npads, mode='constant', constant_values=0)[_npads:] 
2

C'è np.pad:

A = np.array([1, 2, 3, 4, 5]) 
A = np.pad(A, (0, length), mode='constant') 

Per quanto riguarda il caso d'uso, il numero richiesto di zeri per il rilievo può essere calcolato come length = len(A) + 1024 - 1024 % len(A).

2

di riferimento futuro:

def padarray(A, size): 
    t = size - len(A) 
    return np.pad(A, pad_width=(0, t), mode='constant') 

padarray([1,2,3], 8)  # [1 2 3 0 0 0 0 0]