2017-12-15 17 views
3

にリストを持つネストされた辞書を広げ:サブ辞書のためのリストに少なくとも2つの要素があります私は、ネストされた辞書、それによってサブディクショナリの使用リスト持っているパンダのDATAFRAME

nested_dict = {'string1': {69: [1231, 232], 67:[682, 12], 65: [1, 1]}, 
    `string2` :{28672: [82, 23], 22736:[82, 93, 1102, 102], 19423: [64, 23]}, ... } 

を、しかし、もっとあるかもしれない。

私はこの辞書を最初の辞書キー(例えば 'string1'、 'string2'、..)用に1列、サブディレクトリキー用に1列、リスト内の最初の項目の列、次の項目の列などがあります。ここで

は、出力がどのように見えるかです:当然

col1  col2 col3  col4 col5 col6 
string1 69  1231  232 
string1 67  682  12 
string1 65  1  1 
string2 28672 82  23 
string2 22736 82  93  1102 102 
string2 19423 64  23 

、私はpd.DataFrame.from_dictを使用しよう:

new_df = pd.DataFrame.from_dict({(i,j): nested_dict[i][j] 
          for i in nested_dict.keys() 
          for j in nested_dict[i].keys() 
          ... 

は、今私はこだわっています。そして、多くの既存の問題があります。

  1. どのように私は文字列を解析行う(すなわちnested_dict[i].values())各要素が新しいパンダのデータフレームの列であるような?

  2. 実際

  3. 上記例えば要素の列を埋めるしないであろう各フィールドの列を作成しません上記サブディレクトリのKey-Valueペアの各行にstring1が含まれている必要があります。 (col5col6については、NAに0を記入できます)

  4. これらの列の名前を正しく指定する方法がわかりません。

答えて

1

これはおそらく最も洗練されたソリューションではありませんが、これはあなたが探している結果をもたらすはずです。おそらくそれを行うより良い(より多くのpandas方法)です。

あなたのネストした辞書を解析し、辞書のリスト(各行に1つ)を作成しました。

# some sample input 
nested_dict = { 
    'string1': {69: [1231, 232], 67:[682, 12], 65: [1, 1]}, 
    'string2' :{28672: [82, 23], 22736:[82, 93, 1102, 102], 19423: [64, 23]}, 
    'string3' :{28673: [83, 24], 22737:[83, 94, 1103, 103], 19424: [65, 24]} 
} 

# new list is what we will use to hold each row 
new_list = [] 
for k1 in nested_dict: 
    curr_dict = nested_dict[k1] 
    for k2 in curr_dict: 
     new_dict = {'col1': k1, 'col2': k2} 
     new_dict.update({'col%d'%(i+3): curr_dict[k2][i] for i in range(len(curr_dict[k2]))}) 
     new_list.append(new_dict) 

# create a DataFrame from new list 
df = pd.DataFrame(new_list) 

出力:

 col1 col2 col3 col4 col5 col6 
0 string2 28672 82 23  NaN NaN 
1 string2 22736 82 93 1102.0 102.0 
2 string2 19423 64 23  NaN NaN 
3 string3 19424 65 24  NaN NaN 
4 string3 28673 83 24  NaN NaN 
5 string3 22737 83 94 1103.0 103.0 
6 string1  65  1  1  NaN NaN 
7 string1  67 682 12  NaN NaN 
8 string1  69 1231 232  NaN NaN 

入力が常にcol1col2を作成するための十分なデータが含まれているという前提があります。

ループスルーnested_dictです。 nested_dictの各要素も辞書であると仮定する。その辞書もループします(curr_dict)。キー​​とk2は、col1col2の入力に使用されます。残りのキーについては、リストの内容を繰り返し、各要素の列を追加します。

1

ここでは、再帰ジェネレータを使用して入れ子になっている辞書を展開する方法を示します。正確に2つのレベルを持っているとはみなされませんが、それぞれがlistに達するまで各dictを展開し続けます。unrollではなくdictsよりリストのリストを生成

nested_dict = { 
    'string1': {69: [1231, 232], 67:[682, 12], 65: [1, 1]}, 
    'string2' :{28672: [82, 23], 22736:[82, 93, 1102, 102], 19423: [64, 23]}, 
    'string3': [101, 102]} 

def unroll(data): 
    if isinstance(data, dict): 
     for key, value in data.items(): 
      # Recursively unroll the next level and prepend the key to each row. 
      for row in unroll(value): 
       yield [key] + row 
    if isinstance(data, list): 
     # This is the bottom of the structure (defines exactly one row). 
     yield data 

df = pd.DataFrame(list(unroll(nested_dict))) 

ので、列が(この場合は0から5まで)数値的に名前が付けられます。だから、あなたがしたい列ラベルを取得するためにrenameを使用する必要があります。

df.rename(columns=lambda i: 'col{}'.format(i+1)) 

これは、次の結果を返します(追加string3エントリも巻き戻されることに注意してください)。

 col1 col2 col3 col4 col5 col6 
0 string1  69 1231 232.0  NaN NaN 
1 string1  67 682 12.0  NaN NaN 
2 string1  65  1 1.0  NaN NaN 
3 string2 28672 82 23.0  NaN NaN 
4 string2 22736 82 93.0 1102.0 102.0 
5 string2 19423 64 23.0  NaN NaN 
6 string3 101 102 NaN  NaN NaN