web-dev-qa-db-ja.com

NumPyで配列を変形する

次の形式の配列(単なる例)を考えてみましょう。

[[ 0  1]
 [ 2  3]
 [ 4  5]
 [ 6  7]
 [ 8  9]
 [10 11]
 [12 13]
 [14 15]
 [16 17]]

形状は[9,2]です。次に、各列が次のように形状[3,3]になるように配列を変換します。

[[ 0  6 12]
 [ 2  8 14]
 [ 4 10 16]]
[[ 1  7 13]
 [ 3  9 15]
 [ 5 11 17]]

最も明白な(そして確かに「非Pythonic」)ソリューションは、適切な次元でゼロの配列を初期化し、データで満たされる2つのforループを実行することです。言語に準拠したソリューションに興味があります...

38
user1876864
a = np.arange(18).reshape(9,2)
b = a.reshape(3,3,2).swapaxes(0,2)

# a: 
array([[ 0,  1],
       [ 2,  3],
       [ 4,  5],
       [ 6,  7],
       [ 8,  9],
       [10, 11],
       [12, 13],
       [14, 15],
       [16, 17]])


# b:
array([[[ 0,  6, 12],
        [ 2,  8, 14],
        [ 4, 10, 16]],

       [[ 1,  7, 13],
        [ 3,  9, 15],
        [ 5, 11, 17]]])
60
eumiro

numpyには、このタスクに最適なツールがあります( "numpy.reshape") リンクを変更するドキュメントへ

_a = [[ 0  1]
 [ 2  3]
 [ 4  5]
 [ 6  7]
 [ 8  9]
 [10 11]
 [12 13]
 [14 15]
 [16 17]]

`numpy.reshape(a,(3,3))`
_

「-1」トリックを使用することもできます

_`a = a.reshape(-1,3)`
_

「-1」はワイルドカードで、2番目の次元が3のときに、numpyアルゴリズムが入力する数値を決定できるようにします

そうです。これも機能します:a = a.reshape(3,-1)

そしてこれ:a = a.reshape(-1,2)は何もしません

そしてこれ:a = a.reshape(-1,9)は形状を(2,9)に変更します

1
Or_K

結果の再配置には2つの方法があります(例は @ eumiro に続く)。 Einopsパッケージは、このような操作を明確に記述する強力な表記法を提供します

>> a = np.arange(18).reshape(9,2)

# this version corresponds to eumiro's answer
>> einops.rearrange(a, '(x y) z -> z y x', x=3)

array([[[ 0,  6, 12],
        [ 2,  8, 14],
        [ 4, 10, 16]],

       [[ 1,  7, 13],
        [ 3,  9, 15],
        [ 5, 11, 17]]])

# this has the same shape, but order of elements is different (note that each paer was trasnposed)
>> einops.rearrange(a, '(x y) z -> z x y', x=3)

array([[[ 0,  2,  4],
        [ 6,  8, 10],
        [12, 14, 16]],

       [[ 1,  3,  5],
        [ 7,  9, 11],
        [13, 15, 17]]])
0
Alleo