Python - NumPy - 元组作为数组元素
我在大学读计算机专业,现在正在做一个关于奇异值分解的编程项目,跟我的高等数学 III 课程有关。简单来说,我的想法是把一张 m x n 大小的图片转换成一个 m x n 的矩阵,其中每个元素是一个元组,表示该像素的颜色通道(红、绿、蓝),也就是 (r, g, b)。我用 Python 来做这个项目,因为这是我到目前为止学得最好的编程语言。
从我了解的情况来看,Python 通常不太喜欢把元组作为数组的元素。我自己查了一下资料,发现了一个解决办法,就是提前分配数组,像这样:
def image_to_array(): #converts an image to an array
aPic = loadPicture("zorak_color.gif")
ph = getHeight(aPic)
pw = getWidth(aPic)
anArray = zeros((ph,pw), dtype='O')
for h in range(ph):
for w in range(pw):
p = getPixel(aPic, w, h)
anArray[h][w] = (getRGB(p))
return anArray
这个方法在作业的第一部分是有效的,第一部分只是把图片转换成矩阵(不涉及线性代数)。
不过,涉及到 SVD 的部分就变得复杂了。当我调用内置的 numPy svd 函数,使用我从图片构建的数组(每个元素是一个元组)时,我遇到了以下错误:
Traceback (most recent call last):
File "<pyshell#5>", line 1, in -toplevel-
svd(x)
File "C:\Python24\Lib\site-packages\numpy\linalg\linalg.py", line 724, in svd
a = _fastCopyAndTranspose(t, a)
File "C:\Python24\Lib\site-packages\numpy\linalg\linalg.py", line 107, in _fastCopyAndTranspose
cast_arrays = cast_arrays + (_fastCT(a.astype(type)),)
ValueError: setting an array element with a sequence.
这个错误和我最开始遇到的错误是一样的,在我查资料之前,我发现可以通过提前分配数组来允许元组作为元素。
现在的问题是,我才刚上大学的第一个学期,编程水平还不高,而这些 numPy 函数是为专业程序员写的,对我来说有点像黑箱(不过我相信对有经验的人来说会清楚很多)。所以修改这些函数以支持元组比我自己写的函数要复杂得多。我接下来该怎么做呢?我想我应该把相关的 numPy 函数复制到我自己的程序中,然后进行相应的修改?
提前谢谢你的帮助。
2 个回答
我觉得你想要的是一个大小为 ph
乘 pw
乘 3
的 numpy 数组。
anArray = zeros((ph,pw,3))
for h in range(ph):
for w in range(pw):
p = getPixel(aPic, w, h)
anArray[h][w] = getRGB(p)
你只需要确保 getRGB
返回的是一个包含三个元素的列表,而不是一个元组。
与其把数组的元素类型设置为'O'(对象),不如把它设置为元组。你可以查看SciPy手册,里面有一些例子。
在你的情况下,最简单的方法是使用类似下面的代码:
a = zeros((ph,pw), dtype=(float,3))
假设你的RGB值是由三个浮点数构成的元组。
这就像是创建一个三维数组(正如Steve建议的那样),实际上,元组中的元素可以通过a[n,m][k]
或z[n,m,k]
来访问,其中k
是元组中的元素。
当然,SVD是针对二维矩阵定义的,而不是三维数组,所以你不能直接使用linalg.svd(a)
。你需要决定要对哪个矩阵进行SVD(在R、G和B这三个可能的矩阵中)。
例如,如果你想要“R”矩阵的SVD(假设这是元组中的第一个元素),可以使用类似下面的代码:
linalg.svd(a[:,:,1])