Часто, я создаю массив путем итерации через некоторые данные, например:
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", при этом он массив от запуска?
Если я правильно понимаю ваш вопрос, это должно сделать то, что вы хотите:
# 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))
Рекомендуемый способ сделать это - предварительно выделить перед циклом и использовать срезы и индексацию для вставки
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.resize ()
.Это будет намного , намного быстрее, чем постоянное перераспределение массива внутри цикла.
РЕДАКТИРОВАТЬ: В ответ на комментарий @ 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 ++ также делают то же самое).
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])