[python] 사전 목록을 팬더 DataFrame으로 변환

다음과 같은 사전 목록이 있습니다.

[{'points': 50, 'time': '5:00', 'year': 2010},
{'points': 25, 'time': '6:00', 'month': "february"},
{'points':90, 'time': '9:00', 'month': 'january'},
{'points_h1':20, 'month': 'june'}]

그리고 나는 이것을 이렇게 팬더로 바꾸고 DataFrame싶습니다.

      month  points  points_h1  time  year
0       NaN      50        NaN  5:00  2010
1  february      25        NaN  6:00   NaN
2   january      90        NaN  9:00   NaN
3      june     NaN         20   NaN   NaN

참고 : 열 순서는 중요하지 않습니다.

위와 같이 사전 목록을 팬더 DataFrame으로 바꾸려면 어떻게해야합니까?



답변

치죠는 d단순히 dicts의 목록입니다 :

pd.DataFrame(d)


답변

사전 목록을 pandas DataFrame으로 어떻게 변환합니까?

다른 답변은 정확하지만 이러한 방법의 장점과 한계에 대해서는별로 설명되지 않았습니다. 이 게시물의 목적은 다양한 상황에서 이러한 방법의 예를 보여주고 사용시기 (및 사용하지 않을시기)를 논의하고 대안을 제안하는 것입니다.


DataFrame(), DataFrame.from_records().from_dict()

데이터의 구조와 형식에 따라 세 가지 방법이 모두 작동하거나 일부 방법이 다른 방법보다 잘 작동하거나 전혀 작동하지 않는 상황이 있습니다.

매우 고안된 예를 고려하십시오.

np.random.seed(0)
data = pd.DataFrame(
    np.random.choice(10, (3, 4)), columns=list('ABCD')).to_dict('r')

print(data)
[{'A': 5, 'B': 0, 'C': 3, 'D': 3},
 {'A': 7, 'B': 9, 'C': 3, 'D': 5},
 {'A': 2, 'B': 4, 'C': 7, 'D': 6}]

이 목록은 모든 키가있는 “레코드”로 구성됩니다. 가장 간단한 경우입니다.

# The following methods all produce the same output.
pd.DataFrame(data)
pd.DataFrame.from_dict(data)
pd.DataFrame.from_records(data)

   A  B  C  D
0  5  0  3  3
1  7  9  3  5
2  2  4  7  6

사전 오리엔테이션에 대한 단어 : orient='index'/'columns'

계속하기 전에 다른 유형의 사전 방향을 구별하고 팬더를 지원하는 것이 중요합니다. “열”과 “인덱스”의 두 가지 기본 유형이 있습니다.

orient='columns'
“열”방향의 사전은 해당 키가 해당 DataFrame의 열에 해당합니다.

예를 들어, data위는 “열”방향입니다.

data_c = [
 {'A': 5, 'B': 0, 'C': 3, 'D': 3},
 {'A': 7, 'B': 9, 'C': 3, 'D': 5},
 {'A': 2, 'B': 4, 'C': 7, 'D': 6}]

pd.DataFrame.from_dict(data_c, orient='columns')

   A  B  C  D
0  5  0  3  3
1  7  9  3  5
2  2  4  7  6

참고 :를 사용하는 경우 pd.DataFrame.from_records방향은 “열”인 것으로 가정하고 (달리 지정할 수 없음) 사전이 그에 따라로드됩니다.

orient='index'
이 방향으로 키는 색인 값에 해당하는 것으로 가정합니다. 이러한 종류의 데이터는에 가장 적합합니다 pd.DataFrame.from_dict.

data_i ={
 0: {'A': 5, 'B': 0, 'C': 3, 'D': 3},
 1: {'A': 7, 'B': 9, 'C': 3, 'D': 5},
 2: {'A': 2, 'B': 4, 'C': 7, 'D': 6}}

pd.DataFrame.from_dict(data_i, orient='index')

   A  B  C  D
0  5  0  3  3
1  7  9  3  5
2  2  4  7  6

이 사례는 OP에서 고려되지는 않지만 여전히 유용합니다.

맞춤 색인 설정

결과 DataFrame에 사용자 정의 색인이 필요한 경우 index=...인수를 사용하여 설정할 수 있습니다 .

pd.DataFrame(data, index=['a', 'b', 'c'])
# pd.DataFrame.from_records(data, index=['a', 'b', 'c'])

   A  B  C  D
a  5  0  3  3
b  7  9  3  5
c  2  4  7  6

에서 지원하지 않습니다 pd.DataFrame.from_dict.

누락 된 키 / 열 다루기

누락 된 키 / 열 값이있는 사전을 처리 할 때 모든 방법이 기본적으로 작동합니다. 예를 들어

data2 = [
     {'A': 5, 'C': 3, 'D': 3},
     {'A': 7, 'B': 9, 'F': 5},
     {'B': 4, 'C': 7, 'E': 6}]

# The methods below all produce the same output.
pd.DataFrame(data2)
pd.DataFrame.from_dict(data2)
pd.DataFrame.from_records(data2)

     A    B    C    D    E    F
0  5.0  NaN  3.0  3.0  NaN  NaN
1  7.0  9.0  NaN  NaN  NaN  5.0
2  NaN  4.0  7.0  NaN  6.0  NaN

열의 하위 집합 읽기

“모든 열에서 읽지 않으려면 어떻게합니까?” columns=...매개 변수를 사용하여이를 쉽게 지정할 수 있습니다 .

예를 들어, data2위 의 예제 사전에서 “A”, ‘D’및 ‘F’열만 읽으려면 목록을 전달하면됩니다.

pd.DataFrame(data2, columns=['A', 'D', 'F'])
# pd.DataFrame.from_records(data2, columns=['A', 'D', 'F'])

     A    D    F
0  5.0  3.0  NaN
1  7.0  NaN  5.0
2  NaN  NaN  NaN

pd.DataFrame.from_dict기본 방향 “열” 에서는 지원되지 않습니다 .

pd.DataFrame.from_dict(data2, orient='columns', columns=['A', 'B'])

ValueError: cannot use columns parameter with orient='columns'

행의 하위 집합 읽기

이러한 방법 중 어느 것도 직접 지원하지 않습니다 . 반복 할 때 데이터를 반복하여 전체 삭제 를 수행해야합니다 . 예를 들어, 위에서 0 번째 와 2 번째 행만 추출 data2하려면 다음을 사용할 수 있습니다.

rows_to_select = {0, 2}
for i in reversed(range(len(data2))):
    if i not in rows_to_select:
        del data2[i]

pd.DataFrame(data2)
# pd.DataFrame.from_dict(data2)
# pd.DataFrame.from_records(data2)

     A    B  C    D    E
0  5.0  NaN  3  3.0  NaN
1  NaN  4.0  7  NaN  6.0

만병 통치약 : json_normalize 중첩 데이터

위에서 설명한 방법에 대한 강력하고 강력한 대안 json_normalize은 사전 (레코드) 목록과 함께 작동 하는 기능이며 중첩 된 사전도 처리 할 수 ​​있습니다.

pd.io.json.json_normalize(data)

   A  B  C  D
0  5  0  3  3
1  7  9  3  5
2  2  4  7  6

pd.io.json.json_normalize(data2)

     A    B  C    D    E
0  5.0  NaN  3  3.0  NaN
1  NaN  4.0  7  NaN  6.0

다시 전달 된 데이터는 json_normalize사전 목록 (레코드) 형식이어야합니다.

언급 한 바와 같이 json_normalize중첩 된 사전도 처리 할 수 ​​있습니다. 다음은 문서에서 가져온 예입니다.

data_nested = [
  {'counties': [{'name': 'Dade', 'population': 12345},
                {'name': 'Broward', 'population': 40000},
                {'name': 'Palm Beach', 'population': 60000}],
   'info': {'governor': 'Rick Scott'},
   'shortname': 'FL',
   'state': 'Florida'},
  {'counties': [{'name': 'Summit', 'population': 1234},
                {'name': 'Cuyahoga', 'population': 1337}],
   'info': {'governor': 'John Kasich'},
   'shortname': 'OH',
   'state': 'Ohio'}
]

pd.io.json.json_normalize(data_nested,
                          record_path='counties',
                          meta=['state', 'shortname', ['info', 'governor']])

         name  population    state shortname info.governor
0        Dade       12345  Florida        FL    Rick Scott
1     Broward       40000  Florida        FL    Rick Scott
2  Palm Beach       60000  Florida        FL    Rick Scott
3      Summit        1234     Ohio        OH   John Kasich
4    Cuyahoga        1337     Ohio        OH   John Kasich

metarecord_path인수 에 대한 자세한 내용 은 설명서를 확인하십시오.


요약

지원되는 특징 / 기능과 함께 위에서 설명한 모든 방법에 대한 표가 있습니다.

여기에 이미지 설명을 입력하십시오

*를 사용한 orient='columns'다음 조옮김과 같은 효과를 얻습니다 orient='index'.


답변

팬더 16.2에서는 pd.DataFrame.from_records(d)이것을 작동시키기 위해해야했습니다.


답변

다음 pd.DataFrame.from_dict(d)과 같이 사용할 수도 있습니다 .

In [8]: d = [{'points': 50, 'time': '5:00', 'year': 2010},
   ...: {'points': 25, 'time': '6:00', 'month': "february"},
   ...: {'points':90, 'time': '9:00', 'month': 'january'},
   ...: {'points_h1':20, 'month': 'june'}]

In [12]: pd.DataFrame.from_dict(d)
Out[12]:
      month  points  points_h1  time    year
0       NaN    50.0        NaN  5:00  2010.0
1  february    25.0        NaN  6:00     NaN
2   january    90.0        NaN  9:00     NaN
3      june     NaN       20.0   NaN     NaN


답변

나는 몇몇 사람들이 이것을 발견하고 여기서 도움이되는 것을 찾지 못한다는 것을 알고 있습니다. 내가 찾은 가장 쉬운 방법은 다음과 같습니다.

dict_count = len(dict_list)
df = pd.DataFrame(dict_list[0], index=[0])
for i in range(1,dict_count-1):
    df = df.append(dict_list[i], ignore_index=True)

이것이 누군가를 돕기를 바랍니다!


답변

list=[{'points': 50, 'time': '5:00', 'year': 2010},
{'points': 25, 'time': '6:00', 'month': "february"},
{'points':90, 'time': '9:00', 'month': 'january'},
{'points_h1':20, 'month': 'june'}]

간단한 전화 :

pd=DataFrame.from_dict(list, orient='columns', dtype=None)

print(pd)


답변

Pyhton3 :
이전에 나열된 대부분의 솔루션이 작동합니다. 그러나 데이터 프레임의 row_number가 필요하지 않고 각 행 (레코드)을 개별적으로 작성해야하는 경우가 있습니다.

이 경우 다음 방법이 유용합니다.

import csv

my file= 'C:\Users\John\Desktop\export_dataframe.csv'

records_to_save = data2 #used as in the thread. 


colnames = list[records_to_save[0].keys()]
# remember colnames is a list of all keys. All values are written corresponding
# to the keys and "None" is specified in case of missing value 

with open(myfile, 'w', newline="",encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(colnames)
    for d in records_to_save:
        writer.writerow([d.get(r, "None") for r in colnames])