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

时间:2022-06-28 21:23:53

I'm a CS major in university working on a programming project for my Calc III course involving singular-value decomposition. The idea is basically to convert an image of m x n dimensions into an m x n matrix wherein each element is a tuple representing the color channels (r, g, b) of the pixel at point (m, n). I'm using Python because it's the only language I've really been (well-)taught so far.

我是大学的CS专业,从事我的Calc III课程的编程项目,涉及奇异值分解。该想法基本上是将m×n维的图像转换为m×n矩阵,其中每个元素是表示点(m,n)处的像素的颜色通道(r,g,b)的元组。我正在使用Python,因为它是我迄今为止(好)教授的唯一语言。

From what I can tell, Python generally doesn't like tuples as elements of an array. I did a little research of my own and found a workaround, namely, pre-allocating the array as follows:

据我所知,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

This worked correctly for the first part of the assignment, which was simply to convert an image to a matrix (no linear algebra involved).

这适用于赋值的第一部分,它只是将图像转换为矩阵(不涉及线性代数)。

The part with SVD, though, is where it gets trickier. When I call the built-in numPy svd function, using the array I built from my image (where each element is a tuple), I get the following error:

然而,具有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.

This is the same error I was getting initially, before I did some research and found that I could pre-allocate my arrays to allow tuples as elements.

这是我最初得到的同样的错误,在我做一些研究之前发现我可以预先分配我的数组以允许元组作为元素。

The issue now is that I am only in my first semester of (college-level) programming, and these numPy functions written by and for professional programmers are a little too black-box for me (though I'm sure they're much clearer to those with experience). So editing these functions to allow for tuples is a bit more complicated than when I did it on my own function. Where do I need to go from here? I assume I should copy the relevant numPy functions into my own program, and modify them accordingly?

现在的问题是我只在我的第一学期(大学水平)编程中,这些由专业程序员编写的numPy函数对我来说有点太黑了(虽然我确信它们更清晰对有经验的人)。因此,编辑这些函数以允许元组比我在自己的函数上执行它时要复杂一些。我在哪里需要离开这里?我假设我应该将相关的numPy函数复制到我自己的程序中,并相应地修改它们?

Thanks in advance.

提前致谢。

2 个解决方案

#1


10  

Instead of setting the array element type to 'O' (object) you should set it to a tuple. See the SciPy manual for some examples.

不应将数组元素类型设置为“O”(对象),而应将其设置为元组。有关示例,请参见SciPy手册。

In your case, easiest is to use something like

在你的情况下,最简单的是使用类似的东西

a = zeros((ph,pw), dtype=(float,3))

Assuming your RGB values are tuples of 3 floating point numbers.

假设您的RGB值是3个浮点数的元组。

This is similar to creating a 3d array (as Steve suggested) and, in fact, the tuple elements are accessed as a[n,m][k] or z[n,m,k] where k is the element in the tuple.

这类似于创建一个3d数组(正如史蒂夫建议的那样),事实上,元组元素作为[n,m] [k]或z [n,m,k]访问,其中k是元组中的元素。

Of course, the SVD is defined for 2d matrices and not 3d arrays so you cannot use linalg.svd(a). You have to decide SVD of what matrix (of the three possible ones: R G and B) you need.

当然,SVD是为2d矩阵而不是3d数组定义的,所以你不能使用linalg.svd(a)。你必须决定你需要什么矩阵(三个可能的矩阵:R G和B)的SVD。

If, for example, you want the SVD of the "R" matrix (assuming that is the first element of the tuple) use something like:

例如,如果您想要“R”矩阵的SVD(假设它是元组的第一个元素),请使用以下内容:

linalg.svd(a[:,:,1])

#2


2  

I think you want a ph by pw by 3 numpy array.

我想你需要一个由3个numpy数组的ph值。

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)

You just need to make sure getRGB returns a 3-element list instead of a tuple.

您只需要确保getRGB返回一个3元素列表而不是元组。

#1


10  

Instead of setting the array element type to 'O' (object) you should set it to a tuple. See the SciPy manual for some examples.

不应将数组元素类型设置为“O”(对象),而应将其设置为元组。有关示例,请参见SciPy手册。

In your case, easiest is to use something like

在你的情况下,最简单的是使用类似的东西

a = zeros((ph,pw), dtype=(float,3))

Assuming your RGB values are tuples of 3 floating point numbers.

假设您的RGB值是3个浮点数的元组。

This is similar to creating a 3d array (as Steve suggested) and, in fact, the tuple elements are accessed as a[n,m][k] or z[n,m,k] where k is the element in the tuple.

这类似于创建一个3d数组(正如史蒂夫建议的那样),事实上,元组元素作为[n,m] [k]或z [n,m,k]访问,其中k是元组中的元素。

Of course, the SVD is defined for 2d matrices and not 3d arrays so you cannot use linalg.svd(a). You have to decide SVD of what matrix (of the three possible ones: R G and B) you need.

当然,SVD是为2d矩阵而不是3d数组定义的,所以你不能使用linalg.svd(a)。你必须决定你需要什么矩阵(三个可能的矩阵:R G和B)的SVD。

If, for example, you want the SVD of the "R" matrix (assuming that is the first element of the tuple) use something like:

例如,如果您想要“R”矩阵的SVD(假设它是元组的第一个元素),请使用以下内容:

linalg.svd(a[:,:,1])

#2


2  

I think you want a ph by pw by 3 numpy array.

我想你需要一个由3个numpy数组的ph值。

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)

You just need to make sure getRGB returns a 3-element list instead of a tuple.

您只需要确保getRGB返回一个3元素列表而不是元组。