web-dev-qa-db-fra.com

Tableau numpy zéro pad

Quelle est la meilleure façon Pythonic de remplir un tableau avec des zéros à la fin?

def pad(A, length):
    ...

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

Dans mon cas d'utilisation réel, je souhaite en fait ajouter un tableau au multiple de 1024 le plus proche. Ex: 1342 => 2048, 3000 => 3072

28
Basj

numpy.pad avec constant le mode fait ce dont vous avez besoin, où nous pouvons passer un Tuple en second argument pour dire combien de zéros doivent être ajoutés à chaque taille, un (2, 3) _ par exemple va ajouter 2 zéros à gauche et zéros à droite:

Étant donné A comme:

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

Il est également possible de remplir un tableau 2D numpy en passant un tuple de n-uplets comme largeur de remplissage, qui prend le format de ((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]])

Pour votre cas, vous spécifiez le côté gauche comme étant zéro et le côté droit du pad calculé à partir d'une division modulaire:

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

Pour un plus grand 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
53
Psidom

Cela devrait fonctionner:

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

Vous peut-être pourrez obtenir de meilleures performances si vous initialisez un tableau vide (np.empty(length)) puis complétez A et le zeros séparément , mais je doute que les accélérations valent la peine d’avoir une complexité de code supplémentaire dans la plupart des cas.

Pour obtenir la valeur jusqu'à pad, je pense que vous utiliseriez probablement quelque chose comme divmod:

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

Fondamentalement, cela indique simplement combien de fois 1024 divise la longueur de votre tableau (et le reste de cette division). S'il n'y a pas de reste, vous voulez juste des éléments n * 1024. S'il y a un reste, alors vous voulez (n + 1) * 1024.

tous ensemble:

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

Pour référence future:

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]
4
Basj

Vous pouvez aussi utiliser 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])

Et dans une fonction:

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

Il y a np.pad:

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

En ce qui concerne votre cas d'utilisation, le nombre de zéros requis pour le pad peut être calculé comme suit: length = len(A) + 1024 - 1024 % len(A).

2
lballes