Python - NumPy - 元组作为数组的元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4231190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python - NumPy - tuples as elements of an array
提问by Thomas
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.
我是大学的计算机科学专业,正在为我的 Calc III 课程设计一个涉及奇异值分解的编程项目。这个想法基本上是将 mxn 维度的图像转换为 mxn 矩阵,其中每个元素是一个元组,表示点 (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.
提前致谢。
回答by Steve Tjoa
I think you want a phby pwby 3numpy array.
我想你想ph通过pw通过3numpy的阵列。
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 getRGBreturns a 3-element list instead of a tuple.
您只需要确保getRGB返回一个 3 元素列表而不是元组。
回答by nimrodm
Instead of setting the array element type to 'O' (object) you should set it to a tuple. See the SciPy manualfor 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 kis the element in the tuple.
这类似于创建一个 3d 数组(正如 Steve 建议的那样),实际上,元组元素被访问为元组中的元素a[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)。您必须确定您需要的矩阵(三个可能的矩阵:RG 和 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])

