

現在以下の形のリストデータを抽出しました。

[code]

    [['A (S)' 'B (M)']
     ['1234'
      '{  "voltage" : { "name" : { "S" : "R00070" },   "button" : { "L" : [ { "N" : "29" }, { "N" : "0" } ] }']
     ['5678'
      '{  "voltage" : { "name" : { "S" : "R00080" },   "button" : { "L" : [ { "N" : "30" }, { "N" : "1" } ] }']
    ・・・
    ・・・
    ・・・
    
[/code]

上記の形を多重ではなくシンプルなリストへ変換したいと考えています。  
buttonは全く同じパラメータで数値のみ違うので、パラメータ名を分ける必要があります。  
色々調べても全くやり方わからず良い方法を教えて欲しいです。宜しくお願いします。

[code]

    [['A (S)' 'B (M)_voltage_name_s' 'B (M)_button_L_N' 'B (M)_button_L_N1' ]
     ['1234' 'R00070' '29' '0' ]
     ['1234' 'R00080' '30' '1' ]
    ・・・
    ・・・
    ・・・
    
[/code]


CC BY-SA 4.0
2020-06-08T01:22:03.783
67408
2020-06-09T00:11:53.333
38096
question
python3 pandas numpy
以下のリストデータがあり、さらにカラムの中に辞書型のデータがあります。これを以下の形に変換したいのですが、やり方が不明


以下の記事を応用して出来そうです。  
[Python flatten multilevel JSON](https://stackoverflow.com/q/51359783/9014308)  
[Flattening JSON objects in Python](https://towardsdatascience.com/flattening-
json-objects-in-python-f5343c794b10)

ですが、その前に質問記事でいくつか変更を入れます。

  * コメントにあるように、元データも結果データもPythonのリスト・辞書としてはカンマが不足しているので補っておきます。
  * ダブルクォーテーションを全てシングルクォーテーションに変更します。
  * さらに、辞書としては閉じ中括弧`}`が2つ不足しているようですので、これも補っておきます。
  * 合成した後のカラム名の`s`が小文字になっていますが、これは大文字の`S`のままとします。
  * ボタン名やリストのキー名は`L`と`N`のみでカラム数も4で変わらないものとします。(`R`とか`M`とかは増えないしカラムも減らない)

プログラムとしては以下になります。

[code]

    ## サンプルデータ設定
    ## (各データの区切りにカンマを挿入、
    ##  全てシングルクォーテーションに、
    ##  辞書データは最後に } を2つ追加)
    data = \
    [ ['A (S)','B (M)'],
      ['1234',
        { 'voltage' : { 'name' : { 'S' : 'R00070' },
                        'button' : { 'L' : [ { 'N' : '29' }, { 'N' : '0' } ] } } } ],
      ['5678',
        { 'voltage' : { 'name' : { 'S' : 'R00080' },
                        'button' : { 'L' : [ { 'N' : '30' }, { 'N' : '1' } ] } } } ]
    ]
    
    ## 途中の処理が強引なのでこの部分の処理全体をやめて固定のヘッダ行を用意しても良いかもしれない
    def flatten_key(h, d):  ## カラム名作成関数
        out = [h[0]]
        base = h[1]
    
        def flatten(x, name=''):
            if type(x) is dict:
                for a in x:
                    flatten(x[a], name + '_' + a)
            elif type(x) is list:
                name = name.replace('_voltage', '')  ## この行が強引な処理(ボタン名用に'_voltage'削除)
                k = ''
                for a in x[0]:
                    k = a
                for i in range(len(x)):
                    key = name + '_' + k + ( str(i) if (i != 0) else '')
                    out.append(base + key)
            else:
                out.append(base + name)
    
        flatten(d[1])
        return out
    
    header = data.pop(0)  ## カラム名作成用に元のヘッダ行抽出(元のdataからは削除)
    header = flatten_key(header, data[0])  ## 元のヘッダ行とデータの先頭行でカラム名作成関数呼び出し
    
    def flatten_value(d):  ## データ行作成関数
        out = [d[0]]
    
        def flatten(x):
            if type(x) is dict:
                for a in x:
                    flatten(x[a])
            elif type(x) is list:
                i = 0
                for a in x:
                    flatten(a)
                    i += 1
            else:
                out.append(x)
    
        flatten(d[1])
        return out
    
    body = [flatten_value(d) for d in data]  ## リスト内包表記でデータ部分を変換処理
    
    newdata = [header]  ## カラム名とデータを連結して新しいリスト作成と結果表示
    newdata.extend(body)
    print(newdata)
    
[/code]

結果はこうなります。

[code]

    [['A (S)', 'B (M)_voltage_name_S', 'B (M)_button_L_N', 'B (M)_button_L_N1'], ['1234', 'R00070', '29', '0'], ['5678', 'R00080', '30', '1']]
    
[/code]

見映えよく整形すると以下のようになります。

[code]

    [['A (S)', 'B (M)_voltage_name_S', 'B (M)_button_L_N', 'B (M)_button_L_N1'],
     ['1234', 'R00070', '29', '0'],
     ['5678', 'R00080', '30', '1']]
    
[/code]


CC BY-SA 4.0
2020-06-08T23:37:31.467
67427
2020-06-09T00:11:53.333
2020-06-09T00:11:53.333
26370
26370
67408
answer