pandas如何导入json(将JSON转换为Pandas数据帧)
pandas如何导入json(将JSON转换为Pandas数据帧){ "school_name":"ABCprimaryschool" "class":"Year1" "students":[ { "id":"A001" "name":"Tom" "math":60 "physics":66 "chemistry":61 } { "id":"A002" "name":"James" "math":89 "physics":76 "chemistry":51 } { "id":"A003" "
读取数据是任何数据科学项目的第一步。通常,你将使用JSON格式的数据。在本文中,你将学习如何使用Pandas内置函数read_json和json_normalize来处理以下常见问题:
- 从本地文件读取简单json
- 从URL读取简单JSON
- 从JSON对象展开嵌套列表
- 从JSON对象展开嵌套列表和dict
- 从深度嵌套的JSON中提取值
笔记本的源代码:https://github.com/BindiChen/machine-learning/blob/master/data-analysis/027-pandas-convert-json/pandas-convert-json.ipynb
1.从本地文件读取简单JSON
我们从一个简单的例子开始。
[
{
"id":"A001"
"name":"Tom"
"math":60
"physics":66
"chemistry":61
}
{
"id":"A002"
"name":"James"
"math":89
"physics":76
"chemistry":51
}
{
"id":"A003"
"name":"Jenny"
"math":79
"physics":90
"chemistry":78
}
]
要通过Pandas读取JSON文件,我们可以使用read_JSON方法。
df=pd.read_json('data/simple.json')
我们使用df.info()看看。默认情况下,数值列被转换为数值类型,例如,math、physics和chemistry列被转换为int64。
>>>df.info()
<class'pandas.core.frame.DataFrame'>
RangeIndex:3entries 0to2
Datacolumns(total5columns):
#ColumnNon-NullCountDtype
----------------------------
0id3non-nullobject
1name3non-nullobject
2math3non-nullint64
3physics3non-nullint64
4chemistry3non-nullint64
dtypes:int64(3) object(2)
memoryusage:248.0 bytes
2.从URL读取简单JSON
Pandas read_json接受URL。
URL='http://raw.githubusercontent.com/BindiChen/machine-learning/master/data-analysis/027-pandas-convert-json/data/simple.json'
df=pd.read_json(URL)
>>>df.info()
<class'pandas.core.frame.DataFrame'>
RangeIndex:3entries 0to2
Datacolumns(total5columns):
#ColumnNon-NullCountDtype
----------------------------
0id3non-nullobject
1name3non-nullobject
2math3non-nullint64
3physics3non-nullint64
4chemistry3non-nullint64
dtypes:int64(3) object(2)
memoryusage:248.0 bytes
与从本地文件读取相同,它返回一个DataFrame,默认情况下,数值列被转换为数值类型。
3.从JSON对象展开嵌套列表Pandas read_json对于常规的json非常有效,就像我们在前面的示例中所做的那样。对于带有嵌套列表的JSON呢?让我们看看如何将以下JSON转换为DataFrame:
{
"school_name":"ABCprimaryschool"
"class":"Year1"
"students":[
{
"id":"A001"
"name":"Tom"
"math":60
"physics":66
"chemistry":61
}
{
"id":"A002"
"name":"James"
"math":89
"physics":76
"chemistry":51
}
{
"id":"A003"
"name":"Jenny"
"math":79
"physics":90
"chemistry":78
}]
}
用pandas read_json读取。
df=pd.read_json('data/nested_list.json')
在读取了这个JSON之后,我们可以看到嵌套列表被放到了一个单列students中。如何使嵌套列表变平?一个解决方案是应用一个自定义函数来展平students的值。
这当然完成了我们的工作,但它需要额外的代码才能以我们需要的形式获取数据。可以使用Pandas json_normalize函数有效地解决这个问题。
importjson
#使用pythonjson模块加载数据
withopen('data/nested_array.json' 'r')asf:
data=json.loads(f.read())
#展平数据
df_nested_list=pd.json_normalize(data record_path=['students'])
data = json.loads(f.read())使用python json模块加载数据。然后,调用json_normalize并将参数record_path设置为['students']以展平学生中的嵌套列表。
结果看起来不错,但不包括学校名称和班级。为了包含它们,我们可以使用参数meta来指定结果中想要的元数据列表。
#包括学校名称和班级
df_nested_list=pd.json_normalize(
data
record_path=['students']
meta=['school_name' 'class']
)
接下来,我们尝试读取一个更复杂的JSON数据,它有一个嵌套列表和一个嵌套字典。
{
"school_name":"localprimaryschool"
"class":"Year1"
"info":{
"president":"JohnKasich"
"address":"ABCroad London UK"
"contacts":{
"email":"admin@e.com"
"tel":"123456789"
}
}
"students":[
{
"id":"A001"
"name":"Tom"
"math":60
"physics":66
"chemistry":61
}
{
"id":"A002"
"name":"James"
"math":89
"physics":76
"chemistry":51
}
{
"id":"A003"
"name":"Jenny"
"math":79
"physics":90
"chemistry":78
}]
}
当尝试使用read_json读取它时,我们将得到一个ValueError。
为了读取它,我们可以使用json_normalize。
importjson
#使用pythonjson模块加载数据
withopen('data/nested_mix.json' 'r')asf:
data=json.loads(f.read())
#规范化数据
df=pd.json_normalize(data record_path=['students'])
包括class,president和tel,可以使用参数meta指定属性的路径。
df=pd.json_normalize(
data
record_path=['students']
meta=[
'class'
['info' 'president']
['info' 'contacts' 'tel']
]
)
Pandas json_normalize可以在处理json文件中的嵌套数据时完成大部分工作。但是,当你的目标实际上可能是提取一个值时,它会将整个嵌套数据展平。例如,从下面的JSON文件中提取属性math。
{
"school_name":"localprimaryschool"
"class":"Year1"
"students":[
{
"id":"A001"
"name":"Tom"
"grade":{
"math":60
"physics":66
"chemistry":61
}
}
{
"id":"A002"
"name":"James"
"grade":{
"math":89
"physics":76
"chemistry":51
}
}
{
"id":"A003"
"name":"Jenny"
"grade":{
"math":79
"physics":90
"chemistry":78
}
}]
}
如何才能更有效地做到这一点?答案是在glom中使用read_json。
fromglomimportglomdf=pd.read_json('data/nested_deep.json')
df['students'].apply(lambdarow:glom(row 'grade.math'))
060
189
279
Name:students dtype:int64
glom是一个Python库,它允许我们使用。从深度嵌套对象访问属性的符号。
结论Pandas read_json函数是将简单的json转换为pandas数据帧的一种快速方便的方法。在处理嵌套JSON时,我们可以使用Pandas内置的JSON_normalize函数。
希望本文能帮助你节省将JSON数据转换为DataFrame的时间。建议你查看read_json和json_normalizeAPI的文档,并了解可以做的其他事情。
谢谢你的阅读。
请查看笔记本的源代码:https://github.com/BindiChen/machine-learning/blob/master/data-analysis/027-pandas-convert-json/pandas-convert-json.ipynb