2011-05-17 27 views
18

lo que sería la forma más rápida para combinar una lista de matrices numpy en una matriz si se conoce la longitud de la lista y el tamaño de las matrices, lo que es lo mismo ¿para todos?Fusionar una lista de matrices numpy en un array (rápido)

probé dos enfoques:

A se puede ver vstack es más rápido, pero por alguna razón la primera carrera toma tres tiempos más largos que el segundo. Supongo que esto causado por (faltante) preallocation. Entonces, ¿cómo puedo preasignar una matriz para vstack? ¿O conoces un método más rápido?

Gracias!

[ACTUALIZACIÓN]

Quiero (25280, 320) no (80, 320, 320) lo que significa, merged_array = array(list_of_arrays) no funcionará para mí. ¡Gracias Joris por señalar eso!

Salida:

0.547468900681 s merged_array = array(first_list_of_arrays) 
0.547191858292 s merged_array = array(second_list_of_arrays) 
0.656183958054 s vstack first 
0.236850976944 s vstack second 

Código:

import numpy 
import time 
width = 320 
height = 320 
n_matrices=80 

secondmatrices = list() 
for i in range(n_matrices): 
    temp = numpy.random.rand(height, width).astype(numpy.float32) 
    secondmatrices.append(numpy.round(temp*9)) 

firstmatrices = list() 
for i in range(n_matrices): 
    temp = numpy.random.rand(height, width).astype(numpy.float32) 
    firstmatrices.append(numpy.round(temp*9)) 


t1 = time.time() 
first1=numpy.array(firstmatrices) 
print time.time() - t1, "s merged_array = array(first_list_of_arrays)" 

t1 = time.time() 
second1=numpy.array(secondmatrices) 
print time.time() - t1, "s merged_array = array(second_list_of_arrays)" 

t1 = time.time() 
first2 = firstmatrices.pop() 
for i in range(len(firstmatrices)): 
    first2 = numpy.vstack((firstmatrices.pop(),first2)) 
print time.time() - t1, "s vstack first" 

t1 = time.time() 
second2 = secondmatrices.pop() 
for i in range(len(secondmatrices)): 
    second2 = numpy.vstack((secondmatrices.pop(),second2)) 

print time.time() - t1, "s vstack second" 
+2

uso [ 'timeit'] (http://docs.python.org/library/timeit.html) para hacer pruebas de rendimiento simple en Python. Produce resultados más precisos. –

+2

¿Qué dimensiones desea que tenga la matriz fusionada? Debido a '' first1'' es '' (80, 320, 320) '' y '' first2'' es '' (25,280, 320) '' – joris

+0

@joris, gracias por señalarlo. Quiero el segundo, que fue mi enfoque inicial. Lo cambiaré en la pregunta. – Framester

Respuesta

18

Usted tiene 80 matrices de 320x320? Así que es probable que desee utilizar dstack:

first3 = numpy.dstack(firstmatrices) 

Esto devuelve una 80x320x320 matriz tal y como numpy.array(firstmatrices) hace:

timeit numpy.dstack(firstmatrices) 
10 loops, best of 3: 47.1 ms per loop 


timeit numpy.array(firstmatrices) 
1 loops, best of 3: 750 ms per loop 

Si desea utilizar vstack, devolverá una matriz 25600x320:

timeit numpy.vstack(firstmatrices) 
100 loops, best of 3: 18.2 ms per loop 
+0

Hola, eurmiro, lo siento, mi pregunta no estaba clara. De hecho, necesito (25280, 320) y no (80, 320, 320). Ver la actualización de mi pregunta. – Framester

+0

@Framester - bien, entonces vea mi actualización con 'vstack' simple. – eumiro