2017-01-17 11 views
1

У меня есть 3d массив m*n*k и для каждых 2-го слоя я хочу взять подрамник размером i*j. У меня есть массив c размером 2*k координат начала срезов для каждого слоя. Есть ли хороший и простой способ получить то, что мне нужно, без каких-либо циклов?numpy, разные ломтики для разных слоев массива

Пример:

test = np.arange(18).reshape((3,3,2)) 
c = np.array([[0,1], [0, 1]]) 

test[:,:,0] = array([[ 0, 2, 4], 
        [ 6, 8, 10], 
        [12, 14, 16]]) 

test[:,:,1] = array([[ 1, 3, 5], 
        [ 7, 9, 11], 
        [13, 15, 17]]) 

Я хочу, чтобы получить массив

[[[ 0, 9], 
    [ 2, 11]], 

    [[ 6, 15], 
    [ 8, 17]]] 

решения с петлей:

h=2 
w=2 
layers = 2 
F = np.zeros((h,w,layers)) 
for k in range(layers): 
    F[:,:,k] = test[c[0,k]:c[0,k]+h, c[1,k]:c[1,k]+w, k] 
+0

Не могли бы вы рассказать, как вы бы осуществить это с петлями, так как не ясно, на получение ожидаемому о/р от заданных входов? – Divakar

+0

добавлено решение с контуром –

+0

Когда я запускаю код на данных входах, я вижу 'IndexError'. – Divakar

ответ

1

Вот Векторизованный подход использования broadcasting и advanced-indexing -

d0,d1,d2 = np.ogrid[:h,:w,:layers] 
out = test[d0+c[0],d1+c[1],d2] 

Пример запуска -

In [112]: test = np.arange(200).reshape((10,10,2)) 
    ...: c = np.array([[0,1], [0, 1]]) 
    ...: 

In [113]: h=4 
    ...: w=5 
    ...: layers = 2 
    ...: F = np.zeros((h,w,layers)) 
    ...: for k in range(layers): 
    ...:  F[:,:,k] = test[c[0,k]:c[0,k]+h, c[1,k]:c[1,k]+w, k] 
    ...:  

In [114]: d0,d1,d2 = np.ogrid[:h,:w,:layers] 
    ...: out = test[d0+c[0],d1+c[1],d2] 
    ...: 

In [115]: np.allclose(F, out) 
Out[115]: True 
+0

Он не работает, когда h! = W. Я получаю «Ошибка индекса: несоответствие формы» –

+0

@EgorIgnatenkov На самом деле была ошибка. Обновлено. Проверьте это. – Divakar

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

  • Нет связанных вопросов^_^