NumPyのtranspose()メソッドはどのように配列の軸を並べ替えますか?


81
In [28]: arr = np.arange(16).reshape((2, 2, 4))

In [29]: arr
Out[29]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7]],

       [[ 8,  9, 10, 11],
        [12, 13, 14, 15]]])


In [32]: arr.transpose((1, 0, 2))
Out[32]: 
array([[[ 0,  1,  2,  3],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [12, 13, 14, 15]]])

整数のタプルをtranspose()関数に渡すと、どうなりますか?

具体的には、これは3D配列(1, 0 ,2)です。軸のタプルを渡すと、NumPyはどのように配列を変換しますか?これらの整数が参照する行または列を説明できますか?そして、NumPyのコンテキストでの軸番号は何ですか?



2
0は最初の軸、1は2番目、2は3番目などです。この例では、配置する新しい順序axestranspose提供するパラメータです。最初に2番目、次に最初、次に3番目です。
ハイメ

3Dディスプレイには、ブロック、行、列があります。転置により、ブロックと行の順序が切り替わり、列は変更されません。1番目のブロックの2番目の行であったものが、2番目のブロックの1番目の行になります。
hpaulj 2015

回答:


190

配列を転置するために、NumPyは各軸の形状とストライド情報を交換するだけです。歩みは次のとおりです。

>>> arr.strides
(64, 32, 8)

>>> arr.transpose(1, 0, 2).strides
(32, 64, 8)

転置操作が軸0と軸1のストライドを交換したことに注意してください。これらの軸の長さも交換されました(両方の長さが2この例にあります)。

これを行うためにデータをコピーする必要はありません。NumPyは、基礎となるメモリの見方を変更するだけで、新しい配列を構築できます。


歩幅の視覚化

ストライド値は、配列の軸の次の値に到達するためにメモリ内を移動する必要があるバイト数を表します。

これで、3D配列arrは次のようになります(ラベル付きの軸を使用)。

ここに画像の説明を入力してください

この配列は、連続するメモリブロックに格納されます。本質的にそれは一次元です。それを3Dオブジェクトとして解釈するには、NumPyは、次の3つの軸のいずれかに沿って移動するために、特定の一定のバイト数をジャンプする必要があります。

ここに画像の説明を入力してください

各整数は8バイトのメモリを使用するため(int64 dtypeを使用しています)、各次元のストライド値は、ジャンプする必要のある値の数の8倍です。たとえば、軸1に沿って移動するには、4つの値(32バイト)がジャンプされ、軸0に沿って移動するには、8つの値(64バイト)がジャンプされる必要があります。

書くとき、arr.transpose(1, 0, 2)軸0と1を交換しています。転置された配列は次のようになります。

ここに画像の説明を入力してください

NumPyが行う必要があるのは、軸0と軸1のストライド情報を交換することだけです(軸2は変更されていません)。ここで、軸0よりも軸1に沿って移動するには、さらにジャンプする必要があります。

ここに画像の説明を入力してください

この基本的な概念は、配列の軸の任意の順列に対して機能します。転置を処理する実際のコードはCで記述されており、ここにあります


7

ドキュメントで説明されているように

デフォルトでは、寸法を逆にします。それ以外の場合は、指定された値に従って軸を並べ替えます。

したがってaxes、次元の新しい順序を定義するオプションのパラメーターを渡すことができます。

たとえば、RGBVGAピクセル配列の最初の2次元を転置します。

 >>> x = np.ones((480, 640, 3))
 >>> np.transpose(x, (1, 0, 2)).shape
 (640, 480, 3)

1
こんにちは、あなたの答えをありがとう。ただし、ご覧のとおり、arrの形状は(2,2,4)であり、arr.transpose(1,0,2)も(2,2,4)であるため、この問題はまだ理解できません。これは3次元配列です。(1,0,2)を渡したときに配列を変換する方法ですが、1,0,2が参照する行または列を説明できますか?そして、numpyの観点からの軸番号は何ですか?
フランクフー

1
@FrankHuは3D空間で視覚化するため、x、y軸の回転がここで発生します。(1,0,2)は(0,1,2)から置き換えられたため、最初の2軸が切り替わります。0は軸のインデックス番号です。
たとえば

5

C表記では、配列は次のようになります。

int arr[2][2][4]

これは、2つの2D配列を持つ3D配列です。これらの2D配列にはそれぞれ2つの1D配列があり、これらの1D配列にはそれぞれ4つの要素があります。

つまり、3つの次元があります。軸は0、1、2、サイズは2、2、4です。これは、numpyがN次元配列の軸を処理する方法とまったく同じです。

したがって、arr.transpose((1, 0, 2))軸1を取得して位置0に配置し、軸0を配置して位置1に配置し、軸2を配置して位置2に配置します。軸を効果的に並べ替えています。

0 -\/-> 0
1 -/\-> 1
2 ----> 2

言い換えれば、1 -> 0, 0 -> 1, 2 -> 2。宛先軸は常に順番になっているため、必要なのはソース軸を指定することだけです。タプルを次の順序で読み取ります(1, 0, 2)

この場合、[2][2][4]軸0と軸1のサイズが同じであるという理由だけで、新しい配列の次元は再びになります(2)。

さらに興味深いのは、(2, 1, 0)の配列を与える転置です[4][2][2]

0 -\ /--> 0
1 --X---> 1
2 -/ \--> 2

言い換えれば、2 -> 0, 1 -> 1, 0 -> 2。タプルを次の順序で読み取ります(2, 1, 0)

>>> arr.transpose((2,1,0))
array([[[ 0,  8],
        [ 4, 12]],

       [[ 1,  9],
        [ 5, 13]],

       [[ 2, 10],
        [ 6, 14]],

       [[ 3, 11],
        [ 7, 15]]])

あなたはで終わったint[4][2][2]

すべての寸法のサイズが異なると、おそらく理解が深まるので、各軸がどこに移動したかを確認できます。

なぜ最初の内部要素なの[0, 8]ですか?3D配列を2枚の紙として視覚化し、並べる08、1つは1つの紙に、もう1つはもう1つの紙に、両方とも左上に表示されます。転置(2, 1, 0)とは、紙から紙への方向を紙に沿って左から右に、左から右への方向を紙から紙へと移動させたいということです。左から右に4つの要素があったので、代わりに4枚の紙ができました。そして、2つの論文があったので、左から右に2つの要素があります。

ひどいASCIIアートでごめんなさい。 ¯\_(ツ)_/¯


あなたが与えるタプルtranspose()は数学的な順列か何かではないと私は正しいと思いますか?文字通り、「軸をこれらの位置に配置する」という指示だけですか?たとえば、.transpose(p, q, r, s)「軸pを0番目、q1番目、r2番目、s3番目に配置する」と言っている場合はどうでしょうか。または別の方法で見たということb = a.transpose(axes)b.shape == tuple(a.shape[i] for i in axes)
ティム

軸をアスキーアートと交換するという考えは、私の理解を明確にします。どうもありがとう
K_inverse

0

これは、質問と本から例の発信元と思われるデータ分析のためのPythonウェス・マッキニーによると。この機能についてtransposeは、第4.1章で説明しています。配列の転置と軸の交換

高次元の配列の場合、transposeは軸番号のタプルを受け入れて軸を並べ替えます(余分な心の曲がりのため)。

ここで、「順列」は「再配置」を意味するため、軸の順序を再配置します。

の数字は.transpose(1, 0, 2)、元の軸と比較して軸の順序がどのように変更されるかを決定します。を使用.transpose(1, 0, 2)すると、「1番目の斧を2番目の斧に変更する」という意味になります。を使用する.transpose(0, 1, 2)と、変更するものがないため、配列は同じままになります。これがデフォルトの順序です。

(2, 2, 4)サイズが配列された本の例は、1番目と2番目の軸のサイズが同じであるため、あまり明確ではありません。したがって、行arr[0, 1]との並べ替えを除いて、最終結果は変わらないようですarr[1, 0]

各次元のサイズが異なる3次元配列で別の例を試してみると、再配置部分がより明確になります。

In [2]: x = np.arange(24).reshape(2, 3, 4)

In [3]: x
Out[3]: 
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

In [4]: x.transpose(1, 0, 2)
Out[4]: 
array([[[ 0,  1,  2,  3],
        [12, 13, 14, 15]],

       [[ 4,  5,  6,  7],
        [16, 17, 18, 19]],

       [[ 8,  9, 10, 11],
        [20, 21, 22, 23]]])

ここで、元の配列サイズは(2, 3, 4)です。1枚目と2枚目を変更したので(3, 2, 4)サイズになります。再配置がどのように正確に行われたかを詳しく見ると、数字の配列は特定のパターンで変化したようです。@ RobertBの紙の例えを使用して、2つのチャンクの数値を取得し、それぞれをシートに書き込んでから、各シートから1行を取得して配列の1次元を構築すると、3x2x4サイズの配列になります。 、最外層から最内層まで数えます。

[ 0,  1,  2,  3] \ [12, 13, 14, 15]

[ 4,  5,  6,  7] \ [16, 17, 18, 19]

[ 8,  9, 10, 11] \ [20, 21, 22, 23]

さまざまなサイズの配列で遊んで、さまざまな軸を変更して、それがどのように機能するかをよりよく理解することをお勧めします。


-3

a.transpose()[i、j、k] = a [k、j、i]を要約すると

a = np.array( range(24), int).reshape((2,3,4))
a.shape gives (2,3,4)
a.transpose().shape gives (4,3,2)  shape tuple is reversed.

タプルパラメータが渡されると、軸はタプルに従って並べ替えられます。例えば

a = np.array(range(24)、int).reshape((2,3,4))

a [i、j、k]はa.transpose((2,0,1))[k、i、j]と等しい

軸0が2位になります

軸1が3位

軸2物語1位

もちろん、転置に渡されるタプルパラメータの値が一意であり、範囲(軸の数)にあることに注意する必要があります。


OPの質問に対処していません。これは、指定され軸で転置するどうなるかです。
ロバートB

軸が指定されている場合の質問への回答を追加しました。
ラグーラム2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.