Подтвердить что ты не робот

Эффективное создание массивов numpy из понимания списка и в целом

В моей текущей работе я много раз использую методы Numpy и список, и в интересах наилучшей производительности у меня есть следующие вопросы:

Что на самом деле происходит за кулисами, если я создаю массив Numpy следующим образом?

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

Я предполагаю, что сначала python создает обычный список, содержащий значения, затем использует размер списка для выделения массива numpy, а затем копирует значения в этот новый массив. Правильно ли это, или интерпретатор достаточно умен, чтобы понять, что список является только промежуточным и вместо этого скопировать значения напрямую?

Аналогично, если я хочу создать массив numpy из понимания списка с помощью numpy.fromiter():

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

приведет ли этот результат к промежуточному списку создаваемых значений перед тем, как будет отправлен в fromiter()?

С уважением Niels

4b9b3361

Ответ 1

Я считаю, что ответ, который вы ищете, использует generator expressions с numpy.fromiter.

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

Генераторные выражения ленивы - они вычисляют выражение, когда вы перебираете их.

Использование списков в списке делает список, а затем передает его в numpy, в то время как выражения генератора будут давать один за раз.

Python оценивает вещи внутри → out, как и большинство языков (если не все), поэтому использование [<something> for <something_else> in <something_different>] сделает список, а затем перебирает его.

Ответ 2

Вы можете создать свой собственный список и поэкспериментировать с ним, чтобы пролить свет на ситуацию...

>>> 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])