2015-10-06 3 views
1

У меня есть Numpy массив формы держит много (200 в данном примере) монохроматического 64x64 пикселов изображения, таким образом, имеет форму:Numpy: разделение массива случайным образом

>>> a.shape 
(200L, 1L, 64L, 64L) 

Я хочу, чтобы разделить эти изображения в 3-х новых массивов , a1, a2, a3, где они будут содержать 80%, 10%, 10% изображений, соответственно, и я делаю это следующим образом (я не хочу, чтобы они были последовательными в a):

import numpy as np 
import random 

a = --read images from file-- 

a1 = numpy.empty((0,1,64,64)) 
a2 = numpy.empty((0,1,64,64)) 
a3 = numpy.empty((0,1,64,64)) 

for i in range(200): #200 is the number of images 
    temp = a[-1] 
    a = np.delete(a,-1,0) 
    rand = random.random() 
    if rand < 0.8: 
     a1 = np.append(a1,[temp],0) 
    elsif rand < 0.9: 
     a2 = np.append(a2,[temp],0) 
    else: 
     a3 = np.append(a3,[temp],0) 

Я стараюсь подражать pop и append, которые выполняются при O(1) времени в списках, но делает то же самое для массивов numpy? Есть ли способ сделать это более эффективно (быстрее) для большого количества (тысяч) изображений?

ответ

3

Вот один вкладыш с использованием np.vsplit -

a1,a2,a3 = np.vsplit(a[np.random.permutation(a.shape[0])],(160,180)) 

1) Формой проверки:

In [205]: a = np.random.rand(200,1,64,64) 

In [206]: a1,a2,a3 = np.vsplit(a[np.random.permutation(a.shape[0])],(160,180)) 

In [207]: a.shape 
Out[207]: (200, 1, 64, 64) 

In [208]: a1.shape 
Out[208]: (160, 1, 64, 64) 

In [209]: a2.shape 
Out[209]: (20, 1, 64, 64) 

In [210]: a3.shape 
Out[210]: (20, 1, 64, 64) 

2) Проверка стоимости на игрушечные данных, чтобы убедиться, мы собирание случайных изображений, а не подряд для раскалывания:

In [212]: a 
Out[212]: 
array([[5, 8, 4], 
     [7, 7, 6], 
     [3, 2, 7], 
     [1, 4, 8], 
     [4, 1, 0], 
     [2, 1, 3], 
     [6, 5, 2], 
     [2, 4, 5], 
     [6, 6, 5], 
     [5, 2, 5]]) 

In [213]: a1,a2,a3 = np.vsplit(a[np.random.permutation(a.shape[0])],(6,8)) 

In [214]: a1 
Out[214]: 
array([[1, 4, 8], 
     [7, 7, 6], 
     [6, 6, 5], 
     [2, 4, 5], 
     [4, 1, 0], 
     [5, 2, 5]]) 

In [215]: a2 
Out[215]: 
array([[3, 2, 7], 
     [2, 1, 3]]) 

In [216]: a3 
Out[216]: 
array([[6, 5, 2], 
     [5, 8, 4]]) 
+0

Ницца, простое решение, спасибо! Кажется достаточно быстрым с сложностью O (n) в моих простых тестах. Кстати, я знаю, что это не было в моем первоначальном вопросе, но как насчет памяти? Это заканчивается как 'a', так и разделенными частями в памяти, есть ли способ сделать это, не реплицируя' a'? – Cantfindname

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