117

次の構造のネストされた辞書「user_dict」があるとします。

  • レベル 1: UserId (長整数)
  • レベル 2:カテゴリ (文字列)
  • レベル 3:さまざまな属性 (floats、int など)

たとえば、この辞書のエントリは次のようになります。

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 の) の項目は列として取得されます。これは、達成したいこととは逆です (UserId をインデックスとして持つ)。

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

4

7 に答える 7

177

pandas 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
于 2012-11-27T10:05:17.983 に答える
11

そのため、ディクショナリを反復処理するために for ループも使用していましたが、パネルに変換してからデータフレームに変換すると、はるかに高速に動作することがわかりました。あなたが辞書を持っているとしましょう d

import pandas as pd
d
{'RAY Index': {datetime.date(2014, 11, 3): {'PX_LAST': 1199.46,
'PX_OPEN': 1200.14},
datetime.date(2014, 11, 4): {'PX_LAST': 1195.323, 'PX_OPEN': 1197.69},
datetime.date(2014, 11, 5): {'PX_LAST': 1200.936, 'PX_OPEN': 1195.32},
datetime.date(2014, 11, 6): {'PX_LAST': 1206.061, 'PX_OPEN': 1200.62}},
'SPX Index': {datetime.date(2014, 11, 3): {'PX_LAST': 2017.81,
'PX_OPEN': 2018.21},
datetime.date(2014, 11, 4): {'PX_LAST': 2012.1, 'PX_OPEN': 2015.81},
datetime.date(2014, 11, 5): {'PX_LAST': 2023.57, 'PX_OPEN': 2015.29},
datetime.date(2014, 11, 6): {'PX_LAST': 2031.21, 'PX_OPEN': 2023.33}}}

コマンド

pd.Panel(d)
<class 'pandas.core.panel.Panel'>
Dimensions: 2 (items) x 2 (major_axis) x 4 (minor_axis)
Items axis: RAY Index to SPX Index
Major_axis axis: PX_LAST to PX_OPEN
Minor_axis axis: 2014-11-03 to 2014-11-06

ここで pd.Panel(d)[item] はデータフレームを生成します

pd.Panel(d)['SPX Index']
2014-11-03  2014-11-04  2014-11-05 2014-11-06
PX_LAST 2017.81 2012.10 2023.57 2031.21
PX_OPEN 2018.21 2015.81 2015.29 2023.33

次に、コマンド to_frame() を押して、データフレームに変換できます。同様に、reset_index を使用して、長軸と短軸をインデックスではなく列に変換します。

pd.Panel(d).to_frame().reset_index()
major   minor      RAY Index    SPX Index
PX_LAST 2014-11-03  1199.460    2017.81
PX_LAST 2014-11-04  1195.323    2012.10
PX_LAST 2014-11-05  1200.936    2023.57
PX_LAST 2014-11-06  1206.061    2031.21
PX_OPEN 2014-11-03  1200.140    2018.21
PX_OPEN 2014-11-04  1197.690    2015.81
PX_OPEN 2014-11-05  1195.320    2015.29
PX_OPEN 2014-11-06  1200.620    2023.33

最後に、フレームの外観が気に入らない場合は、to_frame() を呼び出す前にパネルの転置関数を使用して外観を変更できます。こちらのドキュメントを参照してください http://pandas.pydata.org/pandas-docs/dev/generated /pandas.Panel.transpose.html

例として

pd.Panel(d).transpose(2,0,1).to_frame().reset_index()
major        minor  2014-11-03  2014-11-04  2014-11-05  2014-11-06
RAY Index   PX_LAST 1199.46    1195.323     1200.936    1206.061
RAY Index   PX_OPEN 1200.14    1197.690     1195.320    1200.620
SPX Index   PX_LAST 2017.81    2012.100     2023.570    2031.210
SPX Index   PX_OPEN 2018.21    2015.810     2015.290    2023.330

お役に立てれば。

于 2014-11-07T14:44:33.207 に答える