¿Construyendo una matriz en numpy / scipy por iteración en Python?

A menudo, estoy creando una matriz mediante la iteración de algunos datos, por ejemplo:

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

Me parece que primero debo crear una lista y luego convertirla (usando “array”) en una matriz. ¿Hay alguna manera de evitar esto? Todas estas llamadas de fundición saturan el código … ¿cómo puedo construir iterativamente “my_array”, siendo una matriz desde el principio?

Si entiendo su pregunta correctamente, esto debería hacer lo que quiere:

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

NumPy proporciona un método ‘fromiter’:

 def myfunc(n): for i in range(n): yield i**2 np.fromiter(myfunc(5), dtype=int) 

cuyos rendimientos

 array([ 0, 1, 4, 9, 16]) 

La forma recomendada de hacer esto es preasignar antes del bucle y usar la segmentación y la indexación para insertar

 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 proporciona un método array.resize() , pero será mucho más lento debido al costo de reasignar la memoria dentro de un bucle. Si debe tener flexibilidad, me temo que la única forma es crear una array partir de una list .

EDITAR: Si le preocupa que esté asignando demasiada memoria para sus datos, usaría el método anterior para sobre-asignar y luego, cuando se completa el ciclo, elimine los bits no utilizados de la matriz usando array.resize() . Esto será mucho , mucho más rápido que reasignar constantemente la matriz dentro del bucle.

EDITAR: En respuesta al comentario de @ user248237, asumiendo que conoce alguna dimensión de la matriz (para simplificar):

 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 

El principio general es “asigne más de lo que cree que necesitará, y si las cosas cambian, cambie el tamaño de la matriz lo menos posible”. Podría pensarse que duplicar el tamaño es excesivo, pero en realidad este es el método utilizado por varias estructuras de datos en varias bibliotecas estándar en otros idiomas ( java.util.Vector hace esto por defecto, por ejemplo. Creo que varias implementaciones de std::vector en C ++ hacer esto también).