2
votes

Numpy Zero Padding pour correspondre à une certaine forme

J'ai un fichier avec des tableaux ou des formes différentes. Je veux zeropad tout le tableau pour qu'il corresponde à la plus grande forme. La plus grande forme est (93,13).

Pour tester cela, j'ai le code suivant:

for index, array in enumerate(mfcc):
    testarray = np.zeros((93,13))
    for index,row in enumerate(array):
        for i in range(0,len(row)-1):
            testarray[index][i]= row[i]
            mfcc[index] = testarray

comment puis-je remplir à zéro ce tableau pour qu'il corresponde à la forme de ( 93,13)? Et finalement, comment puis-je le faire pour des milliers de lignes?

Edit: La solution a été trouvée dans les commentaires:

testarray = np.ones((41,13))


4 commentaires

Cela pourrait vous aider stats.stackexchange.com/questions/297678/...


Merci pour votre réponse. Je ne vois pas comment cela pourrait m'aider. Je cherche juste un code pour remplir mon tableau pour qu'il corresponde à une forme.


Une idée pourrait être de créer la matrice (93,13) et de la remplir avec les valeurs de (41,13).


Pour ce devoir particulier, je ne recherche pas de réponse idiote. Une boucle for suffirait également.


3 Réponses :


3
votes

Si vous voulez remplir vers la droite et vers le bas de votre tableau d'origine en 2D, voici ce que vous voulez:

import numpy as np
a = np.ones((41,11))

desired_rows = 91
desired_cols = 13
b = np.pad(a, ((0, desired_rows-a.shape[0]), (0, desired_cols-a.shape[1])), 'constant', constant_values=0)
print(b)
"""
prints
[[1. 1. 1. ... 1. 0. 0.]
 [1. 1. 1. ... 1. 0. 0.]
 [1. 1. 1. ... 1. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]
 [0. 0. 0. ... 0. 0. 0.]]
"""

Bien sûr, ce n'est pas une solution anti-erreur, par exemple si le nombre de lignes ou de colonnes souhaité est inférieur à la taille correspondante du tableau d'origine, vous obtiendrez ValueError: l'index ne peut pas contenir de valeurs négatives .


0 commentaires

1
votes

Vous pourriez faire comme ça. array est votre tableau d'origine et dans ce cas juste pour le testcase. Utilisez simplement le vôtre.

import numpy as np
array  = [[None] * 10]*10
#print(array)
testarray = np.zeros((93,13))
for index,row in enumerate(array):
    for i in range(0,len(row)-1):
        testarray[index][i]= row[i]


2 commentaires

Merci, ce code fait le travail. Comment implémenter cela dans une boucle For pour parcourir un tableau avec 50 000 tableaux comme celui-ci et remplacer les lignes par les tableaux remplis nouvellement créés?


Notez qu'une boucle for fonctionnera bien moins bien que les solutions basées sur numpy @TvCasteren



4
votes

Voici une approche utilisant np.pad qui peut se généraliser à une forme cible arbitraire:

def florian(array, shape):
    #print(array)
    testarray = np.zeros(shape)
    for index,row in enumerate(array):
        for i in range(0,len(row)-1):
            testarray[index][i]= row[i]

def to_shape(a, shape):
    y_, x_ = shape
    y, x = a.shape
    y_pad = (y_-y)
    x_pad = (x_-x)
    return np.pad(a,((y_pad//2, y_pad//2 + y_pad%2), 
                     (x_pad//2, x_pad//2 + x_pad%2)),
                  mode = 'constant')

a = np.ones((500, 500))
shape = [1000, 1103]

%timeit florian(a, shape)
# 101 ms ± 5.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit to_shape(a, shape)
# 19.8 ms ± 318 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Pour l'exemple proposé:

shape = [100, 121]
to_shape(a, shape).shape
# (100, 121)

Vérifions avec un autre exemple:

a = np.ones((41,13))
shape = [93, 13]
to_shape(a, shape).shape
# (93, 13)

Timings

def to_shape(a, shape):
    y_, x_ = shape
    y, x = a.shape
    y_pad = (y_-y)
    x_pad = (x_-x)
    return np.pad(a,((y_pad//2, y_pad//2 + y_pad%2), 
                     (x_pad//2, x_pad//2 + x_pad%2)),
                  mode = 'constant')


0 commentaires