Numpy: назначение назначения доступно только для чтения - трансляция

55
6

Я начинаю с 2D-массива и хочу передать его в 3D-массив (например, от изображения в оттенках серого до изображения rgb). Это код, который я использую.

>>> img_grey = np.random.randn(4, 4)
>>> img_rgb = np.broadcast_to(np.expand_dims(img_grey, axis=-1), (4, 4, 3))

Это создает массив img_rgb который работает как ожидалось: 3 цветных канала (последнее измерение), каждый срез которых равен исходному изображению в оттенках серого. Однако, если я это сделаю

>>> img_rgb[0, 0, 0] = 0.
ValueError: assignment destination is read-only

Я не могу изменить изображение rgb!

спросил(а) 2018-04-05T16:38:00+03:00 2 года, 3 месяца назад
1
Решение
56

Причина в том, что broadcast_to не создает новый массив в памяти. Вместо этого вы просто получаете представление об исходных данных. Это можно увидеть, проверив флаги.

>>> img_rg.flags
C_CONTIGUOUS : False
F_CONTIGUOUS : False
OWNDATA : False
WRITEABLE : False
ALIGNED : True
UPDATEIFCOPY : False

В частности, флаг OWNDATA имеет значение False (что означает, что массив берет память из другого объекта), а флаг WRITEABLE - False (поэтому вы не можете изменить объект). См. Документацию флажков с числовыми значками.

Обходной путь заключается в создании копии массива.

>>> img_rgb = np.broadcast_to(np.expand_dims(img_grey, axis=-1), (4, 4, 3)).copy()
>>> img_rgb[0, 0, 0] = 0. # works!

Это дает rgb-образу собственное пространство памяти, которое можно изменить без изменения изображения в оттенках серого. Значения OWNDATA и WRITEABLE также равны True.

ответил(а) 2018-04-05T16:38:00+03:00 2 года, 3 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема