德胜云资讯,添加一些关于程序相关的内容,仅供大家学习交流(https://www.wxclwl.com)
日期:2023/04/11 17:02作者:李中冰人气:
原标题:将JSON转换为Pandas数据帧
读取数据是任何数据科学项目的第一步。通常,你将使用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
我们从一个简单的例子开始。
[
{
"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: 3 entries, 0 to 2
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 3 non-null object
1 name 3 non-null object
2 math 3 non-null int64
3 physics 3 non-null int64
4 chemistry 3 non-null int64
dtypes: int64(3), object(2)
memory usage: 248.0+ bytes
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: 3 entries, 0 to 2
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 id 3 non-null object
1 name 3 non-null object
2 math 3 non-null int64
3 physics 3 non-null int64
4 chemistry 3 non-null int64
dtypes: int64(3), object(2)
memory usage: 248.0+ bytes
与从本地文件读取相同,它返回一个DataFrame,默认情况下,数值列被转换为数值类型。
Pandas read_json对于常规的json非常有效,就像我们在前面的示例中所做的那样。对于带有嵌套列表的JSON呢?让我们看看如何将以下JSON转换为DataFrame:
{
"school_name": "ABC primary school",
"class": "Year 1",
"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函数有效地解决这个问题。
import json
# 使用python json模块加载数据
with open(data/nested_array.json,r) as f:
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": "local primary school",
"class": "Year 1",
"info": {
"president": "John Kasich",
"address": "ABC road, 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。
import json
# 使用python json模块加载数据
with open(data/nested_mix.json,r) as f:
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": "local primary school",
"class": "Year 1",
"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。
from glom import glomdf = pd.read_json(data/nested_deep.json)
df[students].apply(lambda row: glom(row, grade.math))
0 60
1 89
2 79
Name: students, dtype: int64
glom是一个Python库,它允许我们使用。从深度嵌套对象访问属性的符号。
Pandas read_json函数是将简单的json转换为pandas数据帧的一种快速方便的方法。在处理嵌套JSON时,我们可以使用Pandas内置的JSON_normalize函数。
希望本文能帮助你节省将JSON数据转换为DataFrame的时间。建议你查看read_json和json_normalizeAPI的文档,并了解可以做的其他事情。返回搜狐,查看更多
责任编辑: