La manière la plus efficace d'inverser un tableau de numpy
croyez-le ou non, après avoir établi le profil de mon code actuel, le fonctionnement répétitif de la réversion des réseaux numpy a englouti une partie énorme du temps de fonctionnement. Ce que j'ai en ce moment est la méthode basée sur une vue commune:
reversed_arr = arr[::-1]
est-ce qu'il y a un autre moyen de le faire plus efficacement, ou est-ce juste une illusion de mon obsession pour une performance irréaliste?
6 réponses
lorsque vous créez reversed_arr
vous créez une vue dans le tableau original. Vous pouvez alors changer le tableau original, et la vue sera mise à jour pour refléter les changements.
est-ce que vous recréez la vue plus souvent que vous n'en avez besoin? Vous devriez pouvoir faire quelque chose comme ceci:
arr = np.array(some_sequence)
reversed_arr = arr[::-1]
do_something(arr)
look_at(reversed_arr)
do_something_else(arr)
look_at(reversed_arr)
Je ne suis pas un expert en numpy, mais il semble que ce serait le moyen le plus rapide de faire les choses à numpy. Si c'est ce que vous faites déjà, je ne pensez pas que vous pouvez l'améliorer.
P. S., Grande discussion de numpy vues ici:
np.fliplr()
renverse le tableau de gauche à droite.
notez que pour les tableaux 1d, vous devez le piéger un peu:
arr1d = np.array(some_sequence)
reversed_arr = np.fliplr([arr1d])[0]
parce que cela ne semble pas encore marqué comme répondu... La réponse de Thomas Arildsen devrait être la bonne: il suffit d'utiliser
np.flipud(your_array)
s'il s'agit d'un tableau 1d (colonne array).
Avec matrizes faire
fliplr(matrix)
si vous voulez inverser les lignes et les flipud(matrix)
si vous voulez retourner les colonnes. Pas besoin de faire de votre tableau de colonne 1d un tableau de ligne 2dimensionnel (matrice avec une couche Aucune) et ensuite de le retourner.
comme mentionné ci-dessus, a[::-1]
ne crée vraiment qu'une vue, donc c'est une opération à temps constant (et en tant que tel ne prend pas plus longtemps que le tableau se développe). Si vous avez besoin du tableau pour être contigu (par exemple parce que vous effectuez de nombreuses opérations vectorielles avec lui), ascontiguousarray
est à peu près aussi rapide que flipup
/ fliplr
:
Code pour générer le plot:
import numpy
import perfplot
perfplot.show(
setup=lambda n: numpy.random.randint(0, 1000, n),
kernels=[
lambda a: a[::-1],
lambda a: numpy.ascontiguousarray(a[::-1]),
lambda a: numpy.fliplr([a])[0]
],
labels=['a[::-1]', 'ascontiguousarray(a[::-1])', 'fliplr'],
n_range=[2**k for k in range(25)],
xlabel='len(a)',
logx=True,
logy=True,
)
je vais développer la réponse précédente au sujet de np.fliplr()
. Voici un code qui montre comment construire un tableau 1d, le transformer en tableau 2d, le retourner, puis le convertir de nouveau en tableau 1D. time.clock()
sera utilisé pour garder le temps, qui est présenté en termes de secondes.
import time
import numpy as np
start = time.clock()
x = np.array(range(3))
#transform to 2d
x = np.atleast_2d(x)
#flip array
x = np.fliplr(x)
#take first (and only) element
x = x[0]
#print x
end = time.clock()
print end-start
Avec l'imprimé de déclaration sans commentaire:
[2 1 0]
0.00203907123594
Avec l'instruction print commenté:
5.59799927506e-05
So, en termes d'efficacité, je pense que c'est décent. Pour ceux d'entre vous qui aiment le faire dans une ligne, voici cette forme.
np.fliplr(np.atleast_2d(np.array(range(3))))[0]
pour qu'il fonctionne avec des nombres négatifs et une longue liste, vous pouvez faire ce qui suit:
b = numpy.flipud(numpy.array(a.split(),float))
où flipud est pour 1D arra