꿈을 향해 on my way
Pandas - json_normalize 문제 총 정리 본문
1. KeyError
: pandas 'json_normalize' 를 쓰다 보면 KeyError가 자주 뜬다. argument 없이 간단한 json 파일을 처리할 땐 문제가 없는데 'record_path' 랑 'meta' argument 를 쓰다 보면 KeyError 가 자주 발생한다. json 파일 형태가 일률적이지 않을 때가 특히 그런데 예를 들어,
response = {'contacts': [{'contact_type': 'individual',
'is_green_match': True,
'is_signatory': True,
'match_score': 101,
'persons': [{'addresses': [{'city': 'NEW YORK',
'line1': '31 W 34TH ST',
'postal_code': '10001',
'state_code': 'NY'}],
'display': 'Ishay Oved',
'emails': [],
'first_name': 'Ishay',
'id': '8e6d391d-0fa8-5e9d-9880-fd1069c4d190',
'jobs': [],
'last_name': 'Oved',
'phones': [],
'urls': []}]},
{'company': {'addresses': [{'city': 'NEW YORK',
'country_code': 'USA',
'line1': '1185 6TH AVE FL 10',
'postal_code': '10036',
'state_code': 'NY'}],
'emails': [],
'id': '2987b8f5-9d94-5858-b065-1fc62b315e80',
'match_score': 53,
'name': '31 WEST 34TH STREET LLC',
'phones': [],
'urls': []},
'contact_type': 'company',
'is_green_match': True,
'is_signatory': False,
'match_score': 53,
'persons': []}],
'owner_update_time': '2021-08-26',
'property_id': '2c1820dc-2a57-5532-8022-0a8840e32da7'}
df_test = pd.json_normalize(
response,
record_path=['contacts', 'company', 'addresses'],
meta = ['property_id',
['contacts', 'company', 'id'],
['contacts', 'company', 'name'],
['contacts', 'company', 'match_score'],
['contacts', 'company', 'employees_total'],
['contacts', 'company', 'sales_volume'],
['contacts', 'company', 'urls'],
['contacts', 'company', 'year_founded'],
['contacts', 'company', 'dba_name'],
['contacts', 'company', 'parent_id']],
record_prefix='company.addresses.',
errors='ignore'
)
를 실행하면, KeyError가 뜬다.
오류가 뜨는 이유는 리스트내 딕셔너리에 해당 키 ('company') 가 없기 때문이다.
해결법은 간단하다. 리스트 안 모든 딕셔너리에 내가 파싱하고자 하는 키 (위의 예에선 'company') 를 심어주는 것.
for i in response['contacts']:
if 'company' not in i.keys():
i.update({'company':[{'addresses':None,'emails':None, 'urls':None}]})
위 코드를 실행하면, 없던 'company' key가 생기고 KeyError 가 사라진다.
여기서 혼란스러운게, KeyError를 방지하기 위해 'errors = 'ignore'' 했는데 왜 KeyError가 또 나오지? 알아야 할 사실이, error argument 는 'meta' 에 적용되고 'record_path' 에는 적용되지 않는다는 점. 따라서, 'record_path' 에서 KeyError 가 발생하면, 'error' argument 로 해결이 안되고 위 해결방법처럼 리스트 안 모든 데이터에 해당 empty value로 해당 key를 만들어주어야 한다.
2. groupby -> convert rows into multiple columns
: 'record_type' 으로 데이터를 쪼개다 보면 하나의 row에 있었으면 하는 데이터가 여러 개의 rows 로 배치되어 있는 경우가 있다. 무슨말인가 하면,
현 상태
data = {'groupId':[1,1,2], 'email':['a1@gmail.com', 'a2@gmail.com', 'a3@gmail.com'],
'type':['office','personal','personal'],'name':['santy','santy','will']}
df = pd.DataFrame(data)
groupId email type name
1 a1@gmail.com office santy
1 a2@gmail.com personal santy
2 a3@gmail.com personal will
이상적인 상태 (groupId 로 그룹핑)
groupId email1 type1 email2 type2 name
1 a1@gmail.com office a2@gmail.com personal santy
2 a3@gmail.com personal na na will
해결법 -> pandas groupby 를 활용.
new_df = (df.assign(col=df.groupby('groupId').cumcount()+1)
.set_index(['groupId','col'])
.unstack('col')
.sort_index(level=(1,0), axis=1)
)
new_df.columns = [f'{x}{y}' for x,y in new_df.columns]
email1 type1 email2 type2
groupId
1 a1@gmail.com office a2@gmail.com personal
2 a3@gmail.com personal NaN NaN
'데이터 사이언스 공부' 카테고리의 다른 글
How to Melt Multi-index Column (0) | 2022.07.24 |
---|---|
Git LFS 무료 데이터 초과 문제 공짜로 해결하기 - DVC (Data Version Control) (2) | 2022.07.23 |
복잡한 JSON 파일 쉽게 처리하기 - 파이썬 (How to flatten complex JSON file in Python) (0) | 2022.04.02 |
Webhook vs API 차이 (0) | 2022.01.26 |
Connect MySQL database with Python (0) | 2021.12.22 |