2016-07-04 16 views
9

Was ist die mehr pythische Art, ein Array am Ende mit Nullen zu füllen?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] 

In meinem realen Anwendungsfall, in der Tat ich ein Array auf das nächste Vielfache von 1024. Ex-Pad will: 1342 => 2048, 3000 => 3072

Antwort

12

numpy.pad mit constant Modus tut, was Sie brauchen, wo wir ein Tupel als zweites Argument übergeben kann zu sagen, wie viele Nullen aufzufüllen auf jeder Größe, eine (2, 3) zum Beispiel wird Pad Nullen auf der linken Seite und Nullen auf der rechten Seite:

Gegeben A als:

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]) 

Es ist auch möglich, ein 2D-Pad numpy Arrays durch ein Tupel von Tupeln als Polsterbreite vorbei, die tak es das Format der ((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]]) 

Für Ihren Fall legen Sie die linke Seite Null und rechte Seitenpolster aus einer modularen Division berechnet:

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

Für einen größeren 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

Dank! Funktioniert es, wenn die ursprüngliche Länge 3000 ist? (Dann soll gepolsterte Länge 3072 sein) – Basj

+0

Es sollte, da die richtige Länge padding hier ist der Unterschied zwischen '1024' und dem modularen Rest' Len (A) durch '' 1024' geteilt. Es sollte einfach zu testen sein. – Psidom

2

Dies sollte funktionieren:

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

Sie könnte der Lage sein, eine etwas bessere Leistung zu erhalten, wenn Sie ein leeres Array (np.empty(length)) initialisieren und füllen dann in A und th e zeros getrennt, aber ich bezweifle, dass die Beschleunigungen in den meisten Fällen zusätzliche Code Komplexität wert wäre.

Um den Wert zu Pad nach oben zu bekommen, ich glaube, Sie würden wahrscheinlich so etwas wie divmod benutzen Sie einfach:

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

Grundsätzlich ist diese Zahlen heraus, wie viele Male 1024 die Länge Ihres Array teilt (und was der Rest dieser Abteilung ist). Wenn es keinen Rest gibt, dann wollen Sie nur n * 1024 Elemente. Wenn ein Rest vorhanden ist, möchten Sie (n + 1) * 1024.

alles zusammen:

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

Dank! Irgendeine Idee für automatisches Auffüllen, um die Länge ein Vielfaches von 1024 zu machen? Ich schreibe etwas, aber es ist in hohem Maße nicht pythonic;) – Basj

+0

@Basj - Sicher, überprüfen Sie mein Update. Ich habe es bisher nicht testen oder so, aber ich denke, es sollte funktionieren ... – mgilson

+0

Dies ist, was 'pad' tut, aber mit vielen Glocken-n-Pfeifen (vorne, hinten, verschiedene Achsen, andere Fill Modi). – hpaulj

1

Sie auch numpy.pad verwenden:

>>> 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]) 

Und in einer Funktion:

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

Es gibt np.pad:

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

In Bezug auf Ihren Anwendungsfall kann die erforderliche Anzahl von Nullen zum Pad als length = len(A) + 1024 - 1024 % len(A) berechnet werden.

2

Für die Zukunft:

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]