将数组提升到特定幂的问题

Problem with taking an array to a certain power

所以我试图在矩阵的特定行和像素之间找到差异,但出现错误。

其中 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

其中 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

如何将整行提高到二次方?这段代码有什么问题?

问题是您将其定义为二维矩阵,而您使用 colorPal[0] 从中获取的切片仍将是二维矩阵(即使维度 1 现在的大小为 1).

如果您尝试将该二维矩阵与其自身相乘,则它要求最后两个维度具有相同的大小,但它们不满足,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]]

或者你可以在类型转换后全部完成 in-place:

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

问题是您使用了 np.matrix。您应该改用 np.array

*-运算符(**-运算符)...

  • 对于 np.matrix矩阵-乘法(和求幂)。
  • 对于 np.arrayelementwise 乘法(和求幂)。

此问题与 np.matrix 中保持维数的切片无关

如果您确实想继续使用 np.matrix,则需要 np.asarray()np.array() 将矩阵转换为数组。然后你就可以享受元素操作了。

请注意 @ 运算符存在并且它被定义为矩阵乘法(在 np.array 对象上)。 A @ B 等同于 np.matmul(A, B)。还有np.dot。这些函数的行为对输入的形状很敏感。