Python - NumPy - 元组作为数组元素

15 投票
2 回答
55271 浏览
提问于 2025-04-16 07:22

我在大学读计算机专业,现在正在做一个关于奇异值分解的编程项目,跟我的高等数学 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 个回答

3

我觉得你想要的是一个大小为 phpw3 的 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 返回的是一个包含三个元素的列表,而不是一个元组。

15

与其把数组的元素类型设置为'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])

撰写回答