Создание массива в numpy / scipy путем итерации в Python? - PullRequest
22 голосов
/ 15 апреля 2010

Часто я строю массив, просматривая некоторые данные, например ::10000

my_array = []
for n in range(1000):
  # do operation, get value 
  my_array.append(value)
# cast to array
my_array = array(my_array)

Я обнаружил, что сначала должен создать список, а затем привести его (используя «массив») к массиву. Есть ли способ обойти это? Все эти вызовы приведения в порядок загромождают код ... как я могу итеративно создать "my_array", когда он изначально является массивом?

Ответы [ 3 ]

32 голосов
/ 16 апреля 2010

NumPy предоставляет метод fromiter:

def myfunc(n):
    for i in range(n):
        yield i**2


np.fromiter(myfunc(5), dtype=int)

, что дает

array([ 0,  1,  4,  9, 16])
15 голосов
/ 15 апреля 2010

Рекомендованным способом сделать это является предварительное выделение перед циклом и использование нарезки и индексации для вставки

my_array = numpy.zeros(1,1000)
for i in xrange(1000):
    #for 1D array
    my_array[i] = functionToGetValue(i)
    #OR to fill an entire row
    my_array[i:] = functionToGetValue(i)
    #or to fill an entire column
    my_array[:,i] = functionToGetValue(i)

numpy обеспечивает метод array.resize(), но это будет намного медленнее из-за стоимости перераспределения памяти внутри цикла. Если вы должны обладать гибкостью, то, боюсь, единственный способ - создать array из list.

РЕДАКТИРОВАТЬ: Если вы беспокоитесь о том, что вы выделяете слишком много памяти для своих данных, я бы использовал вышеописанный метод для перераспределения, а затем, когда цикл завершен, обрежьте неиспользуемые биты массива, используя 1013 *. Это будет далеко , далеко быстрее, чем постоянное перераспределение массива внутри цикла.

РЕДАКТИРОВАТЬ: В ответ на комментарий @ user248237, предполагая, что вы знаете одно измерение массива (для простоты):

my_array = numpy.array(10000, SOMECONSTANT)

for i in xrange(someVariable):
    if i >= my_array.shape[0]:
        my_array.resize((my_array.shape[0]*2, SOMECONSTANT))

    my_array[i:] = someFunction()

#lop off extra bits with resize() here

Общий принцип: «выделите больше, чем вы думаете, и если что-то изменится, измените размер массива как можно меньше». Удвоение размера можно считать чрезмерным, но на самом деле этот метод используется несколькими структурами данных в нескольких стандартных библиотеках на других языках (например, java.util.Vector делает это по умолчанию. Я думаю, что несколько реализаций std::vector в C ++ сделайте это тоже).

0 голосов
/ 15 апреля 2010

Если я правильно понимаю ваш вопрос, это должно сделать то, что вы хотите:

# the array passed into your function
ax = NP.random.randint(10, 99, 20).reshape(5, 4)

# just define a function to operate on some data
fnx = lambda x : NP.sum(x)**2

# apply the function directly to the numpy array
new_row = NP.apply_along_axis(func1d=fnx, axis=0, arr=ax)

# 'append' the new values to the original array
new_row = new_row.reshape(1,4)
ax = NP.vstack((ax, new_row))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...