【问题标题】:Python - NumPy - tuples as elements of an arrayPython - NumPy - 元组作为数组的元素
【发布时间】:2011-05-12 23:37:57
【问题描述】:

我是一名大学计算机科学专业的学生,​​正在为我的 Calc III 课程编写一个涉及奇异值分解的编程项目。这个想法基本上是将 m x n 维的图像转换为 m x n 矩阵,其中每个元素是表示点 (m, 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 函数复制到我自己的程序中,并相应地修改它们?

提前致谢。

【问题讨论】:

  • SVD 仅适用于矩阵。你打算为每个 RGB 通道做一个 SVD 吗?换句话说,即使您形成一个 m x n x 3 数组,也不能只将其传递给 SVD 函数,因为 SVD 是为非任意大小张量的矩阵定义的。

标签: python arrays numpy linear-algebra


【解决方案1】:

我想你想要一个 ph by pw by 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 返回一个 3 元素列表而不是元组。

【讨论】:

  • 当然,这很简单,我只是将 list() 放在 getRGB 周围。但是按照您的更改后,我开始收到一个新错误:文件“C:\Python24\Lib\site-packages\numpy\linalg\linalg.py”,第 720 行,在 svd _assertRank2(a) 文件“C:\Python24 \Lib\site-packages\numpy\linalg\linalg.py",第 116 行,在 _assertRank2 中引发 LinAlgError,'%d 维数组给定。数组必须是 \LinAlgError: 给定的 3 维数组。数组必须是二维的,所以我仍然需要一种方法来拥有一个可以与 numPy 一起使用的“二维”元组矩阵...
  • 再想一想,这甚至没有任何意义。我认为您找不到条目为元组的 2D 矩阵的 SVD,如果存在 3D 矩阵的 SVD 之类的东西,那肯定超出了我的课程和这个项目的范围。我需要弄清楚如何为每个颜色通道执行此操作,然后以某种方式组合这三个矩阵。感谢您的回复。
  • SVD [DeLathauwer 2000] [Mesgarani 2004] 的 3D 版本,但我怀疑这不是您想要的。对于人脸识别等任务,人们经常对整张图像进行矢量化处理,然后将这些矢量连接成一个大矩阵X,大小为 (hw)-by-(num images),*然后X上执行PCA,这相当于X X^T的SVD。我在这里回答了一个相关问题:stackoverflow.com/questions/4171866/…
【解决方案2】:

您应该将其设置为元组,而不是将数组元素类型设置为“O”(对象)。有关示例,请参阅the SciPy manual

在您的情况下,最简单的方法是使用类似

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

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

这类似于创建一个 3d 数组(正如 Steve 建议的那样),实际上,元组元素以 a[n,m][k]z[n,m,k] 访问,其中 k 是元组中的元素。

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

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

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

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 2018-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 2020-12-13
    相关资源
    最近更新 更多