1

わかりました、たとえば、行列を転置する方法を知っています:

A = np.arange(25).reshape(5, 5)
print A
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, 24]])
A.T
array([[ 0,  5, 10, 15, 20],
   [ 1,  6, 11, 16, 21],
   [ 2,  7, 12, 17, 22],
   [ 3,  8, 13, 18, 23],
   [ 4,  9, 14, 19, 24]])

1 次元配列の場合、この ".T" ツールを使用することはできません (理由は正直わかりません) ため、ベクトルを転置するには、パラダイムを変更して使用する必要があります。たとえば、次のようにします。

B = np.arange(5) 
print B
array([0, 1, 2, 3, 4])

そしてB.T、同じ結果が得られるため、このパラダイムの変更を適用して、次を使用します。

B[ :, np.newaxis]
array([[0],
   [1],
   [2],
   [3],
   [4]])

このパラダイムの変化は、数学的に言えば同じファミリーに属し、多くの要素を共有しているという意味で、1 次元ベクトルは 2 次元ベクトル (行列) とまったく異なるエンティティではないため、少し反感を覚えます。もの。

私の質問は、あらゆる種類のテンソルに対して、よりコンパクトで統一された方法で、einsum である numpy の王冠の (時々呼ばれる) 宝石でこの転置を行うことは可能ですか? 私はあなたがするマトリックスのためにそれを知っています

np.einsum('ij->ji', A)

以前と同様に、次のようになりますA.T

array([[ 0,  5, 10, 15, 20],
   [ 1,  6, 11, 16, 21],
   [ 2,  7, 12, 17, 22],
   [ 3,  8, 13, 18, 23],
   [ 4,  9, 14, 19, 24]])

1次元配列でそれを行うことは可能ですか?

前もって感謝します。

4

2 に答える 2

4

はい、次を使用して 1D 配列を転置できますeinsum

In [17]: B = np.arange(5)
In [35]: np.einsum('i,j->ji', np.ones(1), B)
Out[35]: 
array([[ 0.],
       [ 1.],
       [ 2.],
       [ 3.],
       [ 4.]])

しかし、積の合計を計算するので、それは実際にeinsumは目的ではありません。einsumご想像のとおり、単純に新しい軸を追加するよりも遅くなります。

In [36]: %timeit np.einsum('i,j->ji', np.ones(1), B)
100000 loops, best of 3: 5.43 µs per loop

In [37]: %timeit B[:, None]
1000000 loops, best of 3: 230 ns per loop

1D または 2D 配列を転置するための単一の構文を探している場合は、次の 2 つのオプションがあります。

  • 使用np.atleast_2d(b).T:

    In [39]: np.atleast_2d(b).T
    Out[39]: 
    array([[0],
           [1],
           [2],
           [3],
           [4]])
    
    In [40]: A = np.arange(25).reshape(5,5)
    
    In [41]: np.atleast_2d(A).T
    Out[41]: 
    array([[ 0,  5, 10, 15, 20],
           [ 1,  6, 11, 16, 21],
           [ 2,  7, 12, 17, 22],
           [ 3,  8, 13, 18, 23],
           [ 4,  9, 14, 19, 24]])
    
  • 使用np.matrix:

    In [44]: np.matrix(B).T
    Out[44]: 
    matrix([[0],
            [1],
            [2],
            [3],
            [4]])
    
    In [45]: np.matrix(A).T
    Out[45]: 
    matrix([[ 0,  5, 10, 15, 20],
            [ 1,  6, 11, 16, 21],
            [ 2,  7, 12, 17, 22],
            [ 3,  8, 13, 18, 23],
            [ 4,  9, 14, 19, 24]])
    

    Amatrixは のサブクラスですndarray。これは、行列とベクトルを処理するための優れた構文を提供する特殊なクラスです。すべての行列オブジェクト (行列とベクトルの両方) は 2 次元です。ベクトルは、1 つの列または 1 つの行を持つ 2D 行列として実装されます。

    In [47]: np.matrix(B).shape     # one row
    Out[47]: (1, 5)
    
    In [48]: np.matrix(B).T.shape   # one column
    Out[48]: (5, 1)
    

    matrixs とsには他にも違いがありますndarrays。この* 演算子は s の行列乗算を計算しmatrixますが、 の要素ごとの乗算を実行しndarraysます。を使用する場合は 、必ず違いを調べてnp.matrixください。


ところで、NumPy が の転置を定義する方法には、ある種の美しさがありndarraysます。の は、これらのオブジェクトが次元の配列を表すことができるという事実ndndarray暗示していることに注意してください。Nしたがって、これらのオブジェクトが使用する定義が何であれ、ディメンション.Tに適用する必要があります。N

特に、.T 軸の順序を逆にします。

2 次元では、軸の順序を逆にすることは行列の転置と一致します。1 次元では、転置は何もしません。単一の軸の順序を逆にすると、同じ軸が返されます。美しい部分は、この定義が N 次元で機能することです。

于 2016-04-25T12:58:22.837 に答える
0

の基本的なアクションはeinsum、積の合計を実行するすべてのディメンションを反復することです。場合によってはショートカットが必要であり、可能であればビューを返します。

しかし、「i->j」または「i->ij」について文句を言うと思います。左にまだ存在しないインデックスを右に配置することはできません。

einsum('i,j->ji',A,[1])またはいくつかのバリアントが機能する可能性があります。しかし、それははるかに遅くなります。

In [19]: np.einsum('i,j->ij',[1,2,3],[1])
Out[19]: 
array([[1],
       [2],
       [3]])

In [30]: %%timeit x=np.arange(1000)
    ...: y=x[:,None]
1000000 loops, best of 3: 439 ns per loop

In [31]: %%timeit x=np.arange(1000)
    ...: np.einsum('i,j->ij',x,[1])
100000 loops, best of 3: 15.3 µs per loop
于 2016-04-25T12:55:30.883 に答える