26

DataFrame をネストされた辞書に変換する一般的な方法を探しています

これはサンプル データ フレームです

    name    v1  v2  v3
0   A       A1  A11 1
1   A       A2  A12 2
2   B       B1  B12 3
3   C       C1  C11 4
4   B       B2  B21 5
5   A       A2  A21 6

列の数は異なる場合があり、列名も異なります。

このような :

{
'A' : { 
    'A1' : { 'A11' : 1 }
    'A2' : { 'A12' : 2 , 'A21' : 6 }} , 
'B' : { 
    'B1' : { 'B12' : 3 } } , 
'C' : { 
    'C1' : { 'C11' : 4}}
}

これを達成するための最良の方法は何ですか?

私が得た最も近いものはzip関数でしたが、それを複数のレベル(2列)で機能させることができませんでした。

4

5 に答える 5

53

あなたの辞書にa がない理由がわかりませんB2。また、列の値が繰り返される場合にどうしたいのかわかりません(最後の値を除くすべての値です)。最初の値が見落としであると仮定すると、再帰を使用できます。

def recur_dictify(frame):
    if len(frame.columns) == 1:
        if frame.values.size == 1: return frame.values[0][0]
        return frame.values.squeeze()
    grouped = frame.groupby(frame.columns[0])
    d = {k: recur_dictify(g.ix[:,1:]) for k,g in grouped}
    return d

生産する

>>> df
  name  v1   v2  v3
0    A  A1  A11   1
1    A  A2  A12   2
2    B  B1  B12   3
3    C  C1  C11   4
4    B  B2  B21   5
5    A  A2  A21   6
>>> pprint.pprint(recur_dictify(df))
{'A': {'A1': {'A11': 1}, 'A2': {'A12': 2, 'A21': 6}},
 'B': {'B1': {'B12': 3}, 'B2': {'B21': 5}},
 'C': {'C1': {'C11': 4}}}

ただし、パンダ以外のアプローチを使用する方が簡単な場合があります。

def retro_dictify(frame):
    d = {}
    for row in frame.values:
        here = d
        for elem in row[:-2]:
            if elem not in here:
                here[elem] = {}
            here = here[elem]
        here[row[-2]] = row[-1]
    return d
于 2013-11-11T06:37:44.497 に答える
7

次のように簡単に辞書を再構築できます

>>> result = {}
>>> for lst in df.values:
...     leaf = result
...     for path in lst[:-2]:
...        leaf = leaf.setdefault(path, {})
...     leaf.setdefault(lst[-2], list()).append(lst[-1])
...
>>> result
{'A': {'A1': {'A11': [1]}, 'A2': {'A21': [6], 'A12': [2]}}, 'C': {'C1': {'C11': [4]}}, 'B':  {'B1': {'B12': [3]}, 'B2': {'B21': [5]}}}

葉が重ならないことが確実な場合は、最後の行を置き換えます

...     leaf.setdefault(lst[-2], list()).append(lst[-1])

...     leaf[lst[-2]] = lst[-1]

必要な出力を得るには:

>>> result
{'A': {'A1': {'A11': 1}, 'A2': {'A21': 6, 'A12': 2}}, 'C': {'C1': {'C11': 4}}, 'B': {'B1': {'B12': 3}, 'B2': {'B21': 5}}}

テストに使用するサンプル データ:

import pandas as pd
data = {'name': ['A','A','B','C','B','A'],
          'v1': ['A1','A2','B1','C1','B2','A2'],
          'v2': ['A11','A12','B12','C11','B21','A21'],
          'v3': [1,2,3,4,5,6]}
df = pd.DataFrame.from_dict(data)
于 2013-11-11T06:46:46.843 に答える