NumPy配列の転置


191

私はPythonとNumPyを使用しており、「転置」に問題があります。

import numpy as np
a = np.array([5,4])
print(a)
print(a.T)

呼び出しa.Tは配列の転置ではありません。たとえばの場合a[[],[]]正しく転置されますが、の転置が必要です[...,...,...]


同じであるが、転置ではなく、成功した「print a.transpose」も試してみました...
11年

回答:


246

想定どおりに機能しています。1D配列の転置は依然として1D配列です!(Matlabに慣れている場合、基本的に1D配列の概念はありません。Matlabの「1D」配列は2Dです。)

1Dベクトルを2D配列に変換してから転置したい場合は、それをスライスするだけですnp.newaxis(またはNone、同じですが、newaxis読みやすくなります)。

import numpy as np
a = np.array([5,4])[np.newaxis]
print(a)
print(a.T)

一般的に言えば、これについて心配する必要はありません。余分な次元を追加することは、習慣からそれを実行しているだけの場合、たいていは望んでいないことです。Numpyは、さまざまな計算を行うときに1D配列を自動的にブロードキャストします。通常、ベクトルだけが必要な場合は、行ベクトルと列ベクトル(どちらもベクトルではありません。どちらも2Dです)を区別する必要はありません。


2
@thaking- np.arange1D配列をすばやく作成するために使用しました。でもまったく同じように機能しa = np.array([5,4])ます。
Joe Kington、

2
@thaking numpyを初めて使用する場合-角括弧()はnumpyの追加の次元を示していないことに注意してください。場合はa = np.arange(10)、その後aされるarray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])などによって生成さa.__repr__()。これはa.ndim --> 1、角括弧で示される1次元(つまり)ベクトル[]です。array( ... )あなたがいずれかを実行時に見られませんprint(a)a.__str__()
dtlussier

7
@JoeKington 1D配列のブロードキャストが便利な状況があります。配列内のすべての1Dポイント間の距離を計算しています。あなたの解決策のおかげで、距離行列を与えるx-x [np.newaxis] .Tを実行できます
JuanPi

4
個人的には、np.vstack()操作がより明確であると思いますprint np.vstack(a)
Alexander Pozdneev

2
これは単なるmatlabではなく、線形代数には行/列ベクトルの概念があります。Numpyは、Matlabだけでなく、多くの場所から来ている人々にとって特異です。
エリック

133

1つではなく2つのブラケットペアを使用します。これにより、ブラケットペアを1つ使用して作成する1D配列とは異なり、転置可能な2D配列が作成されます。

import numpy as np    
a = np.array([[5, 4]])
a.T

より完全な例:

>>> a = [3,6,9]
>>> b = np.array(a)
>>> b.T
array([3, 6, 9])         #Here it didn't transpose because 'a' is 1 dimensional
>>> b = np.array([a])
>>> b.T
array([[3],              #Here it did transpose because a is 2 dimensional
       [6],
       [9]])

numpyのshapeメソッドを使用して、ここで何が行われているのかを確認します。

>>> b = np.array([10,20,30])
>>> b.shape
(3,)
>>> b = np.array([[10,20,30]])
>>> b.shape
(1, 3)

11
私は[np.newaxis]よりもこのソリューションを好みます。よりエレガントなimoに見えます。
PhilMacKay 2014年

機械はそれほどインテリジェントではありません。妻が1人だけの場合でも、最初の妻として宣言する必要があります。
Sreeragh AR

これが選択された答えになるはずです
ブルーノ

79

1D配列の場合

a = np.array([1, 2, 3, 4])
a = a.reshape((-1, 1)) # <--- THIS IS IT

print a
array([[1],
       [2],
       [3],
       [4]])

ここで-1が「必要な数の行」を意味することを理解したら、これが配列を「転置」する最も読みやすい方法であることがわかります。配列の次元が高い場合は、単にを使用しますa.T


5
これはベクトルでのみ機能することに注意してください。2次元配列がある場合、操作transposereshape配列を異なる方法で変更します(結果の画像の形状は同じですが、要素の配置が異なります)。
johndodo 2017

2
発言ありがとうございます。私はあなたの要点を理解していますが、@ thakingフレームの質問に対する正確な1行のソリューションを提供しているので、それが私の答えを明確にするよりも気を散らすと思います。2次元配列ではなく、1次元配列です。ここにリンゴとナシ。
Ulf Aslak 2017

2
もちろん。この場合、あなたの答えは正しくエレガントです。私はそれを批判するつもりはありません。しかし、質問のタイトル(「NumPy配列の転置」)を考えると、より一般的な解決策を探して多くの訪問者がここに来ると思い、2D配列には適用できないことを警告したいと思いました。それ以外の場合、OPの質問を考えると、答えは正しく、適切です。
johndodo 2017年

@UlfAslak、あなたのアプローチをNDアレイに一般化できないという答えを更新してください。!johndodoの提案に従って常に前もって明確にしておくとよいので、誰もあなたのテクニックを誤って使用しないようにしてください。ここでの質問は正しい答えです&ライナーではありません。
Anu

18

既存のベクトルを追加の角括弧のセットでラップすることにより、行列に変換できます...

from numpy import *
v=array([5,4]) ## create a numpy vector
array([v]).T ## transpose a vector into a matrix

numpyにはmatrixクラスもあります(配列と行列の比較を参照)...

matrix(v).T ## transpose a vector into a matrix

14

numpy 1D配列->列/行行列:

>>> a=np.array([1,2,4])
>>> a[:, None]    # col
array([[1],
       [2],
       [4]])
>>> a[None, :]    # row, or faster `a[None]`
array([[1, 2, 4]])

そして、@ joe-kingtonが言ったように、読みやすくするためにNoneで置き換えることができますnp.newaxis


10

1d配列を2d列に「転置」するには、次を使用できますnumpy.vstack

>>> numpy.vstack(numpy.array([1,2,3]))
array([[1],
       [2],
       [3]])

それはバニラリストでも機能します:

>>> numpy.vstack([1,2,3])
array([[1],
       [2],
       [3]])

1
@sandroscodelller、基礎となるコードを見ましたvstackか? np.concatenate([atleast_2d(_m) for _m in tup], 0)。配列を(1,1)配列に分割し、それらを連結します!その過程でコピーが作成されますが、変形されたものはすべてビューを作成します。
hpaulj

3

転置できるのは2D配列のみです。を使用numpy.matrixして2D配列を作成できます。これは3年遅れですが、可能な解決策のセットに追加しています。

import numpy as np
m = np.matrix([2, 3])
m.T

の使用np.matrixは不要であり、一般的には推奨されません。
hpaulj



2

別のソリューション.... :-)

import numpy as np

a = [1,2,4]

[1、2、4]

b = np.array([a]).T

配列([[1]、[2]、[4]])


このソリューションの問題は何ですか?
omotto 2017年

1

私は上記の投稿を統合しています。他の人が時間を節約するのに役立つことを願っています:

以下の配列には(2, )次元があり、1次元配列です。

b_new = np.array([2j, 3j])  

1次元配列を転置するには2つの方法があります。


"np.newaxis"またはなしでスライスしてください。

print(b_new[np.newaxis].T.shape)
print(b_new[None].T.shape)

他の書き方、上記はT操作なし!

print(b_new[:, np.newaxis].shape)
print(b_new[:, None].shape)

[]をラップするかnp.matrixを使用すると、新しい次元が追加されます。!

print(np.array([b_new]).T.shape)
print(np.matrix(b_new).T.shape)

0

上記のコメントの一部として、1D配列の転置は1D配列であるため、1D配列を転置する1つの方法は、次のように配列を行列に変換することです。

np.transpose(a.reshape(len(a), 1))


0

回答には記載されていないが、ドキュメントには記載されているnumpy.ndarray.transpose方法があります。

1次元配列の場合、転置されたベクトルは単に同じベクトルであるため、これは効果がありません。1次元配列を2次元列ベクトルに変換するには、次元を追加する必要があります。np.atleast2d(a).Tは、a [:, np.newaxis]と同様にこれを実現します。

できること:

import numpy as np
a = np.array([5,4])
print(a)
print(np.atleast_2d(a).T)

どちらの(imo)がを使用するよりも優れていnewaxisます。


0

基本的に、転置機能は、配列の形状とストライドを交換することです。

>>> a = np.ones((1,2,3))

>>> a.shape
(1, 2, 3)

>>> a.T.shape
(3, 2, 1)

>>> a.strides
(48, 24, 8)

>>> a.T.strides
(8, 24, 48)

1D numpy配列(ランク1配列)の場合、形状とストライドは1要素のタプルであり、交換することはできません。そのような1D配列の転置は、それを変更せずに返します。代わりに、「行ベクトル」(形状の数の多い配列)を転置できます。(1, n))を「列ベクトル」()に(n, 1)。これを実現するには、最初に1Dのnumpy配列を行ベクトルに変換してから、形状とストライドを入れ替えます(転置)。以下はそれを行う関数です:

from numpy.lib.stride_tricks import as_strided

def transpose(a):
    a = np.atleast_2d(a)
    return as_strided(a, shape=a.shape[::-1], strides=a.strides[::-1])

例:

>>> a = np.arange(3)
>>> a
array([0, 1, 2])

>>> transpose(a)
array([[0],
       [1],
       [2]])

>>> a = np.arange(1, 7).reshape(2,3)
>>> a     
array([[1, 2, 3],
       [4, 5, 6]])

>>> transpose(a)
array([[1, 4],
       [2, 5],
       [3, 6]])

もちろん、1D配列があり(n, 1)a.reshape((-1, 1))またはによって配列に直接再形成できるので、このようにする必要はありませんa[:, None]。配列の転置がどのように機能するかを示したかっただけです。


0

これを1次元配列に対してコンパクトで読みやすい方法で実装する方法をこれまでに学習しました。

h = np.array([1,2,3,4,5])

v1 = np.vstack(h)
v2 = np.c_[h]

h1 = np.hstack(v1)
h2 = np.r_[v2[:,0]]

numpy.r_および numpy.c_は、スライスオブジェクトをそれぞれ第1軸と第2軸に沿った連結に変換します。したがって、垂直配列v2を水平配列h2に転置する際のスライスv2 [:、0]

numpy.vstackは、形状(N、)の1次元配列が(1、N)に再形成された後の最初の軸に沿った連結と同等です。vsplitで分割された配列を再構築します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.