2016-07-04 3 views
9

Jaki jest bardziej pythonic sposób na tablicę z zerami na końcu?Zero tablica 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] 

W moim przypadku użycia rzeczywistym, w rzeczywistości chcę pad tablicę do najbliższej wielokrotności 1024. Ex: 1342 => 2048, 3000 => 3072

Odpowiedz

12

numpy.pad z trybem constant robi to, co trzeba, gdzie możemy przekazać krotki jako drugi argument, aby powiedzieć, ile zer pad na każdej wielkości, o (2, 3) na przykład będzie pad zer po lewej stronie i zerami z prawej strony:

Biorąc A jak:

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

możliwe jest również, aby pad tablicach 2D numPy przekazując krotka krotek jak szerokość dopełnienia, które tak es format ((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]]) 

Dla Państwa przypadku należy podać lewą stroną do zera i prawy pad boczny obliczona z modułowego podziału:

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

dla większych 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

Dzięki! Czy to działa, jeśli oryginalna długość wynosi 3000? (wtedy długość wyściełana powinna wynosić 3072). – Basj

+0

Powinno, ponieważ prawidłowa długość dopełnienia jest tutaj różnicą pomiędzy '1024' a modularną resztą' len (A) 'podzieloną przez' 1024'. Powinno być łatwe do przetestowania. – Psidom

2

To powinno działać:

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

ty może być w stanie uzyskać nieco lepszą wydajność, jeśli zainicjować pustą tablicę (np.empty(length)), a następnie wypełnić A i Th e zeros osobno, ale wątpię, aby przyspieszenia były warte większej złożoności kodu w większości przypadków.

Aby uzyskać wartość pad do góry, myślę, że pewnie po prostu użyć coś jak divmod:

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

Zasadniczo, to tylko domyśla się, ile razy 1024 dzieli długość tablicy (i jaka jest pozostałość tego podziału). Jeśli nie ma reszty, to po prostu chcesz n * 1024 elementów. Jeśli jest reszta, to chcesz (n + 1) * 1024.

wszystko razem:

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

Dzięki! Masz pomysł na automatyczne dopełnienie, aby długość była wielokrotnością 1024? Piszę coś, ale jest to wysoce nie pythonic;) – Basj

+0

@Basj - Oczywiście, sprawdź moją aktualizację. Nie przetestowałem tego ani nic, ale myślę, że to powinno zadziałać ... – mgilson

+0

To właśnie robi 'pad', ale z wieloma dzwonkami-n-gwizdkami (przód, tył, różne osie, inne tryby wypełniania). – hpaulj

1

Można też użyć 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]) 

A w funkcję:

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

Jest np.pad:

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

Jeśli chodzi o przypadek użycia, wymaganą liczbę zer do podkładki można obliczyć jako length = len(A) + 1024 - 1024 % len(A).

2

Do wykorzystania w przyszłości:

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]