Development Tip

중첩 된 사전의 항목에서 Pandas DataFrame 생성

yourdevel 2020. 11. 30. 20:04
반응형

중첩 된 사전의 항목에서 Pandas DataFrame 생성


구조가있는 중첩 된 사전 '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에 공급하려는 많은 항목이 포함되어 속성에서 시리즈를 구성합니다. 이 경우 계층 적 인덱스가 목적에 유용합니다.

특히, 내 질문은 DataFrame 생성자가 사전의 "수준 3"값에서 시리즈를 작성해야한다는 것을 이해하는 데 도움이되는 방법이 있는지 여부입니다.

다음과 같이 시도하면 :

df = pandas.DataFrame(users_summary)

"레벨 1"(사용자 ID)의 항목은 열로 간주됩니다. 이는 내가 달성하려는 것과 반대입니다 (사용자 ID를 인덱스로 사용).

사전 항목을 반복 한 후 시리즈를 구성 할 수 있다는 것을 알고 있지만보다 직접적인 방법이 있다면 이것은 매우 유용 할 것입니다. 비슷한 질문은 파일에 나열된 json 객체에서 pandas DataFrame을 구성 할 수 있는지 여부를 묻는 것입니다.


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

그래서 저는 딕셔너리를 반복하는 데에도 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

도움이 되었기를 바랍니다.


pd.concat accepts a dictionary. With this in mind, it is possible to improve upon the currently accepted answer in terms of simplicity and performance by use a dictionary comprehension to build a dictionary mapping keys to sub-frames.

pd.concat({k: pd.DataFrame(v).T for k, v in user_dict.items()}, axis=0)

Or,

pd.concat({
        k: pd.DataFrame.from_dict(v, 'index') for k, v in user_dict.items()
    }, 
    axis=0)

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

참고URL : https://stackoverflow.com/questions/13575090/construct-pandas-dataframe-from-items-in-nested-dictionary

반응형