web-dev-qa-db-ja.com

リスト内包表記および一般的なnumpy配列の効率的な作成

私の現在の仕事では、Numpyを使用し、内包表記をたくさん使用します。可能な限り最高のパフォーマンスを得るために、次の質問があります。

Numpy配列を次のように作成すると、実際に舞台裏で何が起こりますか? :

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

私の推測では、python最初に値を含む通常のリストを作成し、リストサイズを使用してnumpy配列を割り当て、その後、値をこの新しい配列にコピーします。これは正しいですか、またはインタープリターは、リストが中間のみであり、代わりに値を直接コピーすることを理解するのに十分賢いですか?

同様に、numpy.fromiter()を使用してリスト内包表記からnumpy配列を作成する場合:

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

これにより、fromiter()に入力される前に、中間値のリストが作成されますか?

敬具Niels

36
NielsGM

あなたが探している答えよりもgenerator expressions with numpy.fromiter

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

ジェネレータ式は怠zyです-それらを反復するときに式を評価します。

リスト内包表記を使用すると、リストが作成されてからnumpyにフィードされますが、ジェネレーター式では一度に1つが生成されます。

Pythonは、ほとんどの言語(すべてではないにしても)のように、内部->外部を評価するため、[<something> for <something_else> in <something_different>]はリストを作成し、それを繰り返します。

40

独自のリストを作成し、それを試して状況に光を当てることができます...

>>> 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
wim