Эффективное создание массивов 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
Ответы
Ответ 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])