2016-12-05 2 views
-1

В настоящее время я использую numpy для создания массива. Я хотел бы использовать векторизованные реализации для более эффективного усреднения элементов в позиции (i, j). Эти массивы поступают из изображений в каталоге файлов, все из которых стандартизованы до фиксированного размера.Почему максимальное значение элемента в массиве numpy 255?

Однако, когда я пытаюсь добавить массивы изображений, сумма каждого элемента возвращается в форме a (mod 256). Как изменить максимальное значение элементов?

+0

Я бы сказал, что ваш массив имеет тип 'uint8'. Используйте 'numpy.astype' для создания другого массива с требуемым типом переменной. Например, 'y = x.astype (numpy.uint16)'. –

ответ

1

Ваших массивов предположительно типа numpy.uint8, поэтому они оберточные, когда они попали 256.

Если вы хотите, чтобы получить большие результаты, использовать astype преобразовать первый аргумент большего типа данных, например:

a = np.array(..., dtype=np.uint8) 
b = np.array(..., dtype=np.uint8) 
c = a.astype(np.uint32) + b 

, и вы получите массив результатов большего типа данных.

Per @Eric, чтобы избежать временного, вы можете использовать the numpy add function (не метод), чтобы сделать добавление, пропускание dtype поэтому результат нового типа, даже как входы не преобразуются, избегая временное (по крайней мере, уровень Python):

c = np.add(a, b, dtype=np.uint32) 
+0

Или еще лучше, используйте 'c = np.add (a, b, dtype = np.uint32)', чтобы избежать создания временной копии 'a' (что на 4 раза больше, чем' a') – Eric

+0

@ Эрик: я попробовал что-то вроде этого, но, видимо, документы интерактивного интерпретатора и [numpy online docs] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.add.html#numpy.add) лгали мне (они только упоминали параметр «out», и на самом деле он не избежал проблемы с переполнением). Добавил это к ответу; Я хотел чего-то подобного в первую очередь. – ShadowRanger

+2

Я думаю, вы должны знать о 'ufuncs', чтобы знать, что параметр доступен: https://docs.scipy.org/doc/numpy/reference/ufuncs.html – Benjamin

0

Вы бы лучше создать выходной массив первых:

average = numpy.zeros(a.shape, numpy.float32) 
image = numpy.zeros_like(average) 

Затем обход изображения и добавлять их на месте:

for i in images: 
    image[:] = function_that_reads_images_as_uint8(i) 
    average += image 
average /= len(images) 

Вы можете уйти с типами типов, если вам не нужна точность на этапе деления.

+0

Или вы могли бы просто написать' np.mean (изображения, dtype = np.float32) ', что позволяет избежать ручного цикла, который вы никогда не должны использовать в numpy. – Eric

+1

@ Эрик: Если вы не готовы складывать все изображения в один многодисковый ndarray (который может быть непомерно высоким для памяти для большого количества изображений), этот подход превосходит. Мой подход требует только двух массивов одинаковой формы, один для просматриваемого изображения, другой для результата. Я также очень удивлен, увидев такие заявления о зацикливании. Цикл может быть признаком того, что вы не в полной мере используете векторизацию, но это отнюдь не зло, особенно когда дело доходит до работы с большими данными или наборами данных, в которых использование памяти является проблемой. – Benjamin

+0

Для вашего подхода требуется 3 массива, потому что '.astype (numpy.float32)' делает ненужную копию. Но вы правы, я не рассматривал ограничения памяти в этом комментарии, и в этом случае цикл является разумным – Eric

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