Création efficace de tableaux numpy à partir de la compréhension de la liste et en général

Dans mon travail actuel je utiliser Numpy et interprétations de la liste beaucoup et dans l'intérêt de la meilleure performance possible, j'ai les questions suivantes:

Que se passe-t-il réellement dans les coulisses si je crée un tableau Numpy comme suit? :

a = numpy.array( [1,2,3,4] )

Je suppose que python crée d'abord une liste ordinaire contenant les valeurs, puis utilise la taille de la liste pour allouer un tableau numpy et copie ensuite les valeurs dans ce nouveau tableau. Est-ce correct, ou l'interprète est-il assez intelligent pour réalisez que la liste n'est qu'intermédiaire et copiez les valeurs directement?

De même, si je souhaite créer un tableau numpy à partir de la compréhension de la liste en utilisant numpy.fromiter ():

a = numpy.fromiter( [ x for x in xrange(0,4) ], int )

Cela entraînera-t-il la création d'une liste intermédiaire de valeurs avant d'être introduite dans fromiter()?

Cordialement Niels

29
demandé sur NielsGM 2013-01-17 09:17:46

2 réponses

Je crois que la réponse que vous cherchez utilise generator expressions avec numpy.fromiter.

numpy.fromiter((<some_func>(x) for x in <something>),<dtype>,<size of something>)

Les expressions du générateur sont paresseuses - elles évaluent l'expression lorsque vous les parcourez.

L'utilisation des compréhensions de liste crée la liste, puis la nourrit dans numpy, tandis que les expressions du générateur donneront une à la fois.

Python évalue les choses à l'intérieur - > out, comme la plupart des langages (sinon tous), donc en utilisant [<something> for <something_else> in <something_different>] ferait la liste, puis itérer dessus.

35
répondu Snakes and Coffee 2015-03-20 14:53:45

Vous pouvez créer votre propre liste et l'expérimenter pour faire la lumière sur la situation...

>>> class my_list(list):
...     def __init__(self, arg):
...         print 'spam'
...         super(my_list, self).__init__(arg)
...   def __len__(self):
...       print 'eggs'
...       return super(my_list, self).__len__()
... 
>>> x = my_list([0,1,2,3])
spam
>>> len(x)
eggs
4
>>> import numpy as np
>>> np.array(x)
eggs
eggs
eggs
eggs
array([0, 1, 2, 3])
>>> np.fromiter(x, int)
array([0, 1, 2, 3])
>>> np.array(my_list([0,1,2,3]))
spam
eggs
eggs
eggs
eggs
array([0, 1, 2, 3])
8
répondu wim 2017-09-07 18:53:56