Проблема с возведением массива в определенную степень

Итак, я пытаюсь получить разницу между определенной строкой матрицы и пикселем, и я получаю сообщение об ошибке.

Где colorPal — матрица 8x3:

colorPal = np.matrix('0., 0., 0.;'
                    '0., 0., 1.;'
                    '0., 1., 0.;'
                    '0., 1., 1.;'
                    '1., 0., 0.;'
                    '1., 0., 1.;'
                    '1., 1., 0.;'
                    '1., 1., 1.;')

, и я пытаюсь вычесть три значения из каналов RGB из определенной строки этой матрицы:

colorPal[0] - pix

где пикс:

    a certain pixel with 3 channels (RGB) from image, 
and I'm accesing it by specifying row and column of that image (img):
    
So, pix = img[i,j]

Для первой строки colorPal и определенных значений пикселей:

colorPal[0] = [[0. 0. 0.]]
pix = [0.81 0.81 0.81]

И после этой операции выше (colorPal[0] - pix) я получаю результат:

[[-0.81 -0.81 -0.81]]

Так что это вычитается. Теперь я хочу возвести весь этот ряд во вторую степень ((colorPal[0] - pix)**2). Но numpy выдает это:

raise LinAlgError('Last 2 dimensions of the array must be square')                                                                                   
numpy.linalg.LinAlgError: Last 2 dimensions of the array must be square

Как мне возвести весь этот ряд во вторую степень? Что не так в этом коде?

Какую версию numpy и Python вы используете? Ваш исходный фрагмент кода не будет работать на Python 3.10 и numpy 1.22.0. (финал ; оскорбляет)

Grismar 06.04.2022 01:02

Странный. У меня python 3.10.4, а numpy 1.21.5.

todovvox 06.04.2022 01:11
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
33
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Проблема в том, что вы определяете его как 2D-матрицу, и срез, который вы берете из него с помощью colorPal[0], по-прежнему будет 2D-матрицей (даже несмотря на то, что 1 измерение теперь имеет размер 1).

Если вы попытаетесь умножить эту 2D-матрицу на себя, потребуется, чтобы последние два измерения имели одинаковый размер, а они не имеют, 1 != 3.

Вы можете сделать это:

import numpy as np


colorPal = np.matrix('0., 0., 0.;'
                     '0., 0., 1.;'
                     '0., 1., 0.;'
                     '0., 1., 1.;'
                     '1., 0., 0.;'
                     '1., 0., 1.;'
                     '1., 1., 0.;'
                     '1., 1., 1.')

pix = np.array([0.81, 0.81, 0.81])

print((np.asarray(colorPal[0]).squeeze() - pix) ** 2)

Это берет срез и превращает его в массив с тем же размером и измерениями, а затем сжимает его, чтобы превратить его в одномерный массив, который можно умножать сам на себя по мере необходимости.

Результат:

[0.6561 0.6561 0.6561]

Или вы можете избежать сложности, сначала превратив все colorPal в массив, поэтому вам не нужно выполнять преобразование для каждого цвета:

import numpy as np


colorPal = np.matrix('0., 0., 0.;'
                     '0., 0., 1.;'
                     '0., 1., 0.;'
                     '0., 1., 1.;'
                     '1., 0., 0.;'
                     '1., 0., 1.;'
                     '1., 1., 0.;'
                     '1., 1., 1.')

pix = np.array([0.81, 0.81, 0.81])
colorPal = np.asarray(colorPal)

print((colorPal[0] - pix) ** 2)

Тот же результат.

Из вашего комментария к этому ответу видно, что вы действительно хотите изменить или заменить colorPal операцией, применяемой к каждому цвету. Как только вы превратите свою матрицу в массив, это легко:

import numpy as np


colorPal = np.matrix('0., 0., 0.;'
                     '0., 0., 1.;'
                     '0., 1., 0.;'
                     '0., 1., 1.;'
                     '1., 0., 0.;'
                     '1., 0., 1.;'
                     '1., 1., 0.;'
                     '1., 1., 1.')

pix = np.array([0.81, 0.81, 0.81])
result = (np.asarray(colorPal) - pix) ** 2

print(result)

Результат:

[[0.6561 0.6561 0.6561]
 [0.6561 0.6561 0.0361]
 [0.6561 0.0361 0.6561]
 [0.6561 0.0361 0.0361]
 [0.0361 0.6561 0.6561]
 [0.0361 0.6561 0.0361]
 [0.0361 0.0361 0.6561]
 [0.0361 0.0361 0.0361]]

Или вы можете сделать все это на месте после преобразования типа:

colorPal = np.asarray(colorPal)
colorPal -= pix
colorPal *= colorPal

Я вижу, я вижу. Но как именно это работает? Если я распечатаю colorPal после и до преобразования, внутренности выглядят одинаково. Это просто изменение типа объекта?

todovvox 06.04.2022 01:28
colorPal выглядит одинаково, потому что код не изменяет его (или только меняет тип) — я только показывал, почему вы получаете ошибку, которую вы получали, и как ее обойти. Если вы хотите обновить сам colorPal или сохранить результат вычисления где-то еще, см. мое обновление к ответу.
Grismar 06.04.2022 01:40

Проблема в том, что вы используете np.matrix. Вместо этого вы должны использовать np.array.

*-оператор (**-оператор)...

  • для np.matrix это матрица-умножение (и возведение в степень).
  • для np.array это умножение поэлементно (и возведение в степень).

Проблема ничего связана с фрагментами из np.matrix, поддерживающими количество измерений.

Если вы хотите продолжать использовать np.matrix, вам понадобятся np.asarray() или np.array() для преобразования матриц в массивы. Затем вы можете наслаждаться поэлементными операциями.

Обратите внимание, что существует @-оператор, и он определен как умножение матриц (для объектов np.array). A @ B эквивалентно np.matmul(A, B). Также существует np.dot. Поведение этих функций чувствительно к формам входных данных.

Другие вопросы по теме