web-dev-qa-db-ja.com

Python-NumPy-配列の要素としてのタプル

私は大学のCS専攻で、特異値分解を含むCalcIIIコースのプログラミングプロジェクトに取り組んでいます。アイデアは基本的に、m xn次元の画像をmx 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関数を自分のプログラムにコピーし、それに応じて変更する必要があると思いますか?

前もって感謝します。

13
Thomas

配列要素タイプを「O」(オブジェクト)に設定する代わりに、タプルに設定する必要があります。いくつかの例については、 SciPyマニュアル を参照してください。

あなたの場合、最も簡単なのは次のようなものを使用することです

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

RGB値が3つの浮動小数点数のタプルであると仮定します。

これは(Steveが提案したように)3D配列の作成に似ており、実際、タプル要素はa[n,m][k]またはz[n,m,k]としてアクセスされます。ここで、kはタプルの要素です。

もちろん、SVDは3D配列ではなく、2D行列に対して定義されているため、linalg.svd(a)を使用することはできません。必要なマトリックス(3つの可能なマトリックス:R GとB)のSVDを決定する必要があります。

たとえば、「R」行列のSVDが必要な場合(タプルの最初の要素であると想定)、次のようなものを使用します。

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

ph by pw by 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)

getRGBがタプルではなく3要素のリストを返すことを確認する必要があります。

3
Steve Tjoa