

n次元のnumpy配列をdataframeに変換する際、dataframeの1列目には1次元目のインデックス、2列目には2次元目のインデックス、・・・n列目にはn次元目のインデックス、n+1列目に配列の要素、となるようなデータフレームの作成方法をご教示賜りたいと存じます。

今までは、以下のとおり、行数が配列の要素数、列数がn+1列の2次元のnumpy配列を用意しておき、forループをn回繰り返して2次元配列を作成し、dataframeに変換しておりましたが、さすがに10次元くらいになるとインデントも深すぎて飽きてきます。

[code]

    mynp = np.zeros(m1*m2*m3*...*mn, n+1)
    
    for l1 in range(m1):
        for l2 in range(m2):
            for l3 in range(m3):
                 ……
                     for ln in range(mn):
                         mynp[l1*m2*m3*m4***mn,l2*m3*m4****mn,...,ln] = x[l1,l2,...,ln]
    
    mypd = pd.DataFrame(mynp)
    
    
[/code]


CC BY-SA 4.0
2019-09-03T12:43:37.517
57813
2019-09-10T06:41:59.100
35514
question
python pandas numpy
numpy配列をdataframeに変換する際に、インデックスを付与する方法について


各インデックスの直積を取得してリストに保存したものの末尾に、配列の要素を追加したリストを  
データフレームにアペンドしていくコードになります。  
次元数を増やす場合には、shape変数に配列のサイズを入力してください

[code]

    import itertools
    import numpy as np
    import pandas as pd
    
    shape = (2, 3, 3)
    a_3d = np.arange(18).reshape(*shape)
    ll = [tuple(range(i)) for i in shape]
    df = pd.DataFrame(columns=list(range(len(shape)+1)))
    for index, index_product in enumerate(itertools.product(*ll)):
            row = list(index_product)
            row.append(a_3d[index_product])
            df.loc[index] = row
    
    print(df)
    
[/code]

このコードでは、サンプルとして次の入力を与えています。

[code]

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

得られる出力は次のようになります。

[code]

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


CC BY-SA 4.0
2019-09-03T16:19:14.537
57818
2019-09-04T08:32:20.707
2019-09-04T08:32:20.707
19500
19500
57813
answer


`numpy.indices()` を使うことで、以下のようにループ無しにシンプルに実装できるかと思います。

[code]

    idx = np.indices(arr.shape).reshape(arr.ndim, -1)
    ret = np.vstack([idx, arr.reshape(-1)]).T
    
[/code]

<https://docs.scipy.org/doc/numpy/reference/generated/numpy.indices.html>

* * *

以下動作サンプル

[code]

    import numpy as np
    import pandas as pd
    
    arr = np.arange(5*4*3*2).reshape(5,4,3,2)
    idx = np.indices(arr.shape).reshape(arr.ndim, -1)
    ret = np.vstack([idx, arr.reshape(-1)]).T
    df = pd.DataFrame(ret)
    #     0  1  2  3    4
    #0    0  0  0  0    0
    #1    0  0  0  1    1
    #2    0  0  1  0    2
    #3    0  0  1  1    3
    #4    0  0  2  0    4
    #..  .. .. .. ..  ...
    #115  4  3  0  1  115
    #116  4  3  1  0  116
    #117  4  3  1  1  117
    #118  4  3  2  0  118
    #119  4  3  2  1  119
    
[/code]


CC BY-SA 4.0
2019-09-06T02:04:18.033
57886
2019-09-10T06:41:59.100
2019-09-10T06:41:59.100
754
24801
57813
answer