2011-05-17 1 views
18

Какой бы быстрый способ объединить список массивов numpy в один массив, если вы знаете длину списка и размер массивов, что является одним и тем же для всех?Объединение списка массивов numpy в один массив (быстрый)

Я попробовал два подхода:

вы можете увидеть vstack быстрее, но по каким-то причинам первый запуск занимает три раз длиннее второго. Я предполагаю, что это вызвано (отсутствием) preallocation. Итак, как бы я выделил массив для vstack? Или вы знаете более быстрый метод?

Спасибо!

[UPDATE]

Я хочу (25280, 320) не (80, 320, 320) значит, merged_array = array(list_of_arrays) не будет работать для меня. Спасибо Джорису за это указание!

Выход:

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 

Код:

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

Используйте ['timeit'] (http://docs.python.org/library/timeit.html) для простого тестирования производительности в Python. Это дает более точные результаты. –

+2

Какие размеры вы хотите иметь объединенный массив? Поскольку '' first1'' '' (80, 320, 320) '' и '' first2'' '' (25280, 320) '' – joris

+0

@joris, спасибо, что указали это. Я хочу второй, который был моим первоначальным подходом. Я изменю его в вопросе. – Framester

ответ

18

У вас есть 80 массивов 320x320? Таким образом, вы, вероятно, хотите использовать dstack:

first3 = numpy.dstack(firstmatrices) 

Это возвращает один 80x320x320 массив так же, как numpy.array(firstmatrices) делает:

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 

Если вы хотите использовать vstack, он будет возвращать 25600x320 массив:

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

Привет, эврими, извините, мой вопрос был неясным. Мне действительно нужно (25280, 320), а не (80, 320, 320). См. Обновление моего вопроса. – Framester

+0

@Framester - хорошо, а затем посмотрите мое обновление с помощью простого 'vstack'. – eumiro

Смежные вопросы