2017-01-26 3 views
3

У меня есть многополосный растровый, имеющий 23 полосы, например. Я читаю растровое изображение с помощью GDAL и преобразовываю его в массив numpy. В numpy, когда я проверяю форму массива, он отображается как 23,4,5 i.e. 23 = bands, 4 = row and 5 = col. Я хочу пропустить каждый пиксель таким образом, чтобы я мог получить вектор/массив из всех 23 значений, связанных с одним пикселем.Петля через каждый пиксель в многодиапазонном растере в Python

Я объясняю его дальше подробно на примере ...

Band 1 
    [[1, 2, 3, 4, 5], 
    [6, 7, 8, 9, 10], 
    [11, 12, 13, 14, 15], 
    [16, 17, 18, 19, 20]] 
Band 2 
    [[21, 22, 23, 24, 25], 
    [26, 27, 28, 29, 30], 
    [31, 32, 33, 34, 35], 
    [36, 37, 38, 39, 40]] 
Band 3 
    [[31, 32, 33, 34, 35], 
    [36, 37, 38, 39, 40], 
    [41, 42, 43, 44, 45], 
    [46, 47, 48, 49, 50]] 
Band 4 
    [[41, 42, 43, 44, 45], 
    [46, 47, 48, 49, 50], 
    [51, 52, 53, 54, 55], 
    [56, 57, 58, 59, 60]] 

Теперь я хочу, чтобы перебрать все полосы таким образом, что я должен получить массив значений [1,21,31,41] in first iteration and [2,22,32,42] in second iteration и так далее. Я могу сделать это в R, используя функцию указателя math и извлечения, но в python я не могу этого сделать, потому что у меня очень мало опыта с циклизацией и индексированием массива в python.

Я попробовал некоторые коды, приведенные на StackOverflow

for cell in arr: 
    print cell 

for cell in arr.flat: 
    print cell 

for row in arr: 
    for cell in row: 
     print cell 

for (i,row) in enumerate(arr): 
    for (j,value) in enumerate(row): 
     print value 

Выход я получаю не по мере необходимости.

+0

Что бы вы ни пытались сделать, есть более эффективный способ. Посмотрите на индексы индексирования numpy, numpy.reshape и т. Д. Обычно вы должны иметь возможность векторизовать вычисления и избегать большинства циклов. Если вы дадите нам более подробную информацию о том, что происходит в цикле, мы можем указать вам в правильном направлении. – Benjamin

ответ

1

Как я вижу, вам нужно иметь значения пикселей одинаковых index, сгруппированных вместе. Для группирования же индекс е использование zip здесь с самого bandx не является плоской, мы можем первым flatten тогда группа, и затем сделать zip на flattend полосах

Вот пример с 3 полосы

band1 = np.array([[1, 2, 3, 4, 5], 
    [6, 7, 8, 9, 10], 
    [11, 12, 13, 14, 15], 
    [16, 17, 18, 19, 20]]) 
band2 = np.array([[21, 22, 23, 24, 25], 
    [26, 27, 28, 29, 30], 
    [31, 32, 33, 34, 35], 
    [36, 37, 38, 39, 40]]) 
band3 = np.array([[31, 32, 33, 34, 35], 
    [36, 37, 38, 39, 40], 
    [41, 42, 43, 44, 45], 
    [46, 47, 48, 49, 50]]) 
arr = [band1,band2,band3] 

Вслед даст You массив tuples, как вы ожидали

zip(*map(lambda x:x.flatten(),arr)) 

Если полосы не являются numpy массивов, но нормальные питона массивов , Вы можете сделать следующее

zip(*map(lambda x:x.flatten(),np.array(arr))) 
+0

спасибо за ответ. Да, я правильно понял, мне нужно значение пикселя того же индекса. Мне нужно больше разъяснений. На самом деле у меня 23 группы. Нужно ли преобразовывать каждую группу отдельно в виде массива np. В настоящее время я использую следующий код для чтения растрового и преобразования растра в массив numpy. from osgeo import gdal >>> import numpy as np >>> infile = "F: /PHD_work/peak_modification/test.img" >>> data = gdal.Open (infile) >>> arr = данные. ReadAsArray() –

+0

Каков тип группы сейчас.Я подсчитал, что они являются массивом numpy, так как существует метка для numpy –

+0

, вы можете сделать np.array из результата 'ReadAsArray'. Здесь я обновил ответ –

1

Простой способ использует np.nditer:

>>> for i in np.nditer((Band1, Band2, Band3, Band4)): 
...  print(i) 

Печатается

(array(1), array(21), array(31), array(41)) 
(array(2), array(22), array(32), array(42)) 
(array(3), array(23), array(33), array(43)) 
(array(4), array(24), array(34), array(44)) 
(array(5), array(25), array(35), array(45)) 
(array(6), array(26), array(36), array(46)) 
(array(7), array(27), array(37), array(47)) 
(array(8), array(28), array(38), array(48)) 
(array(9), array(29), array(39), array(49)) 
(array(10), array(30), array(40), array(50)) 
(array(11), array(31), array(41), array(51)) 
(array(12), array(32), array(42), array(52)) 
(array(13), array(33), array(43), array(53)) 
(array(14), array(34), array(44), array(54)) 
(array(15), array(35), array(45), array(55)) 
(array(16), array(36), array(46), array(56)) 
(array(17), array(37), array(47), array(57)) 
(array(18), array(38), array(48), array(58)) 
(array(19), array(39), array(49), array(59)) 
(array(20), array(40), array(50), array(60)) 

Несмотря на то, что кажется странным, что это возвращает массив на самом деле делает его действительно потому что это вид исходного массива, поэтому у вас нет накладных расходов на распаковку значения в виде типа python, и эти нульмерные массивы ведут себя (почти), как родные типы python.

+0

i [0] результаты в массиве (1 , dtype = uint16); int (i [0]) дает нам 1 – addcolor