1. ホーム
  2. python

[解決済み] ネストした辞書の項目からpandasのDataFrameを構築する

2022-05-15 16:54:45

質問

user_dict "をネストした構造を持つ辞書があるとします。

  • レベル1です。 UserId (長い整数)
  • レベル2です。 カテゴリ (文字列)
  • レベル3です。 属性の詰め合わせ(float、ints、など)。

例えば、この辞書の項目は次のようになります。

user_dict[12] = {
    "Category 1": {"att_1": 1, 
                   "att_2": "whatever"},
    "Category 2": {"att_1": 23, 
                   "att_2": "another"}}

の各項目は user_dict は同じ構造を持ち user_dict には大量のアイテムが含まれており、これをpandasのDataFrameにフィードして、属性から系列を構築したいと思います。この場合、階層的なインデックスは目的のために有用である。

具体的には、私の質問は、シリーズが辞書の"レベル3"の値から構築されるべきであることをDataFrameコンストラクタが理解するのを助ける方法が存在するのでしょうか?

もし私が次のようなことを試すなら。

df = pandas.DataFrame(users_summary)

レベル1"の項目(UserId's)は列として扱われ、これは私が達成したいこと(UserId'sをインデックスとして持つ)とは逆のことです。

私は、辞書エントリを反復した後にシリーズを構築することができることを知っていますが、より直接的な方法がある場合、これは非常に便利です。同様の質問は、ファイルにリストされた json オブジェクトから pandas DataFrame を構築することが可能かどうかを尋ねるものです。

どのように解決するのですか?

pandasのMultiIndexはタプルのリストで構成されています。したがって、最も自然なアプローチは、入力dictを再形成して、そのキーが必要なMultiIndexの値に対応するタプルになるようにすることです。そして、データフレームは pd.DataFrame.from_dict を使って、データフレームを構築することができます。 orient='index' :

user_dict = {12: {'Category 1': {'att_1': 1, 'att_2': 'whatever'},
                  'Category 2': {'att_1': 23, 'att_2': 'another'}},
             15: {'Category 1': {'att_1': 10, 'att_2': 'foo'},
                  'Category 2': {'att_1': 30, 'att_2': 'bar'}}}

pd.DataFrame.from_dict({(i,j): user_dict[i][j] 
                           for i in user_dict.keys() 
                           for j in user_dict[i].keys()},
                       orient='index')


               att_1     att_2
12 Category 1      1  whatever
   Category 2     23   another
15 Category 1     10       foo
   Category 2     30       bar

別のアプローチとして、コンポーネントデータフレームを連結してデータフレームを構築することもできます。

user_ids = []
frames = []

for user_id, d in user_dict.iteritems():
    user_ids.append(user_id)
    frames.append(pd.DataFrame.from_dict(d, orient='index'))

pd.concat(frames, keys=user_ids)

               att_1     att_2
12 Category 1      1  whatever
   Category 2     23   another
15 Category 1     10       foo
   Category 2     30       bar