Pour répondre à votre question, oui. L'ajout à un tableau est une opération coûteuse, tandis que les listes le rendent relativement bon marché (voir Internals of Python list, access and resizing runtimes pour la raison). Cependant, ce n'est pas une raison pour abandonner numpy. Il existe d'autres façons d'ajouter facilement des données à un tableau numérique.
Il existe des moyens surprenants (pour moi, de toute façon) de le faire. Passer en bas pour voir les repères pour chacun d'entre eux.
Probablement est tout simplement à preallocate le plus commun du tableau, et l'indice dans ce,
#using preallocated numpy
start = time.time()
array = np.zeros(N)
for i in range(N):
array[i] = i
end = time.time()
print ("Using preallocated numpy: ", round(end-start, 5), end="\n")
Bien sûr, vous pouvez preallocate la mémoire pour une liste aussi, donc permet d'inclure que pour une comparaison de référence .
#using preallocated list
start = time.time()
res = [None]*N
for i in range(N):
res[i] = i
res = np.array(res)
end = time.time()
print ("Using preallocated list : ", round(end-start, 5), end="\n")
En fonction de votre code, il peut également être utile d'utiliser la fonction de numpy fromiter
, qui utilise les résultats d'une iterator pour initialiser le tableau.
#using numpy fromiter shortcut
start = time.time()
res = np.fromiter(range(N), dtype='float64') # Use same dtype as other tests
end = time.time()
print ("Using fromiter : ", round(end-start, 5), end="\n")
Bien sûr, en utilisant un construit en iterator est pas très souple pour nous allons essayer un itérateur personnalisé ainsi,
#using custom iterator
start = time.time()
def it(N):
i = 0
while i < N:
yield i
i += 1
res = np.fromiter(it(N), dtype='float64') # Use same dtype as other tests
end = time.time()
print ("Using custom iterator : ", round(end-start, 5), end="\n")
Voilà deux façons très souples d'utilisation numpy
. Le premier, utilisant un tableau pré-alloué, est le plus flexible. Voyons voir comment ils se comparent:
Using numpy: 2.40017
Using list : 0.0164
Using preallocated numpy: 0.01604
Using preallocated list : 0.01322
Using fromiter : 0.00577
Using custom iterator : 0.01458
Juste à côté, vous pouvez voir que Préallocation fait numpy
beaucoup plus rapide que d'utiliser des listes, bien que la liste préallocation apporte à la fois à la même vitesse. L'utilisation d'un itérateur intégré est extrêmement rapide, bien que les performances de l'itérateur retombent dans la plage de la matrice préallouée et se lisent lorsqu'un itérateur personnalisé est utilisé.
La conversion du code directement au numpy
a souvent des performances médiocres, comme avec append
. Trouver une approche en utilisant les méthodes de numpy
peut presque toujours donner une amélioration substantielle. Dans ce cas, préallouer le tableau ou exprimer le calcul de chaque élément comme un itérateur pour obtenir des performances similaires aux listes python. Ou utilisez une liste de vanille python puisque la performance est à peu près la même.
EDIT: La réponse originale est également np.fromfunction
.Cela a été supprimé car il ne correspondait pas au cas d'utilisation d'un élément à la fois, fromfunction
initialise réellement le tableau et utilise la diffusion de numpy
pour effectuer un seul appel de fonction. Il est environ cent fois plus rapide, donc si vous pouvez résoudre votre problème en utilisant la radiodiffusion ne vous embêtez pas avec ces autres méthodes.
Oui, '.append' est un temps constant constant (amorti) avec des objets' list', avec des objets 'numpy.ndarray' il est linéaire ti.e –
Y at-il un moyen de faire' .append' à 'numpy .ndarray' de la même manière que 'list'? –
Les tableaux Numpy sont conçus pour contenir des matrices potentiellement multidimensionnelles où l'ajout ne peut pas être aussi efficace que dans le cas simple 1D. Généralement dans le code, vous verriez des appels np.zeros (forme) en allouant suffisamment d'éléments à l'avance, où vous connaissez déjà la taille de vos données. Si vous avez besoin d'ajouter trop souvent, vous devriez probablement vous en tenir aux listes intégrées. – lomereiter