官网地址:https://pandas.pydata.org/pandas-docs/version/0.17.0/generated/pandas.io.json.json_normalize.html
先看简单的dict如何转化df:
只要一行代码:pd.DataFrame(data)就可以完成
data = {'user_id': '100001',
'user_name': '小明',
'addr': '北京市',
'phone': '130****0000',
'describe': [{'subject': '英语', 'score': 80},
{'subject': '数学', 'score': 90},
{'subject': '语文', 'score': 85}
]
}
pd.DataFrame(data)
但是当字典结构变得复杂时,出现多层字典嵌套,上面的方法就不是适用了。
报错信息: Mixing dicts with non-Series may lead to ambiguous ordering。
data = {'user_id': '100001',
'user_name': '小明',
'info': {
'addr': '北京市',
'phone': '130****0000'
},
'describe': [{'subject': '英语', 'score': 80},
{'subject': '数学', 'score': 90},
{'subject': '语文', 'score': 85}
]
}
如果传入的是列表,可以正常解析,但是结果不是我们想要的。可以看到describe里面的内容没有扩展成多行。
data = [{'user_id': '100001',
'user_name': '小明',
'info': {
'addr': '北京市',
'phone': '130****0000'
},
'describe': [{'subject': '英语', 'score': 80},
{'subject': '数学', 'score': 90},
{'subject': '语文', 'score': 85}
]
}
]
pd.DataFrame(data)
现在我们引入今天要说的包--json_normalize,看怎么解决这个问题。
from pandas.io.json import json_normalize
data = [{'user_id': '100001',
'user_name': '小明',
'info': {
'addr': '北京市',
'phone': '130****0000'
},
'describe': [{'subject': '英语', 'score': 80},
{'subject': '数学', 'score': 90},
{'subject': '语文', 'score': 85}
]
}
]
df = json_normalize(data,['describe'],['user_id','user_name',['info','addr'],['info','phone']])
df
只要两行代码,问题被完美解决了。如何生成json_normalize所需参数,可以参考一下代码。
agr1=[]
agr2=[]
for key,value in data[0].items():
if isinstance(value, list):
agr1.append(key)
elif isinstance(value, dict):
for j in data[0][key].keys():
l=[]
l.append(key)
l.append(j)
agr2.append(l)
else:
agr2.append(key)
print(agr1,agr2)
再对df列进行处理即可。
df.columns = [i.split('.')[1] if len(i.split('.')) > 1 else i for i in df.columns]
df
列表元素数可以随意增加不受影响
from pandas.io.json import json_normalize
data = [{'user_id': '100001',
'user_name': '小明',
'info': {
'addr': '北京市',
'phone': '130****0000'
},
'describe': [{'subject': '英语', 'score': 80},
{'subject': '数学', 'score': 90},
{'subject': '语文', 'score': 85}]
},
{'user_id': '100002',
'user_name': '小兰',
'info': {
'addr': '北京市',
'phone': '130****0001'
},
'describe': [{'subject': '英语', 'score': 100},
{'subject': '数学', 'score': 80},
{'subject': '语文', 'score': 805}
]
},
]
df = json_normalize(data,['describe'],['user_id','user_name',['info','addr'],['info','phone']])
df.columns = [i.split('.')[1] if len(i.split('.')) > 1 else i for i in df.columns]
df
加油⛽️~