python解析JSON文本
json.load():将一个存储在文件中的json对象(str)转化为相对应的python对象json.loads():将一个json对象(str)转化为相对应的python对象json.dump():将python的对象转化为对应的json对象(str),并存放在文件中json.dumps(): 将python的对象转化为对应的json对象(str)
json.load():将一个存储在文件中的json对象(str)转化为相对应的python对象
json.loads():将一个json对象(str)转化为相对应的python对象
json.dump():将python的对象转化为对应的json对象(str),并存放在文件中
json.dumps(): 将python的对象转化为对应的json对象(str)
3. 使用Python处理JSON文件
在Python中内置了用于读取JSON文件的函数。
以下给出几个如何将JSON文件解析为Python对象的示例。
3.1. 将JSON文件读取为字典类型
首先我们需要导入 json库, 接着我们使用open函数来读取JSON文件,最后利用json.load()函数将JSON字符串转化为Python字典形式.
就这么简单,代码如下:
import json
with open('superheroes.json') as f:
superHeroSquad = json.load(f)
print(type(superHeroSquad)) # Output: dict
print(superHeroSquad.keys())
# Output: dict_keys(['squadName', 'homeTown', 'formed', 'secretBase', 'active', 'members'])
上述代码很简单很直观啦,唯一需要注意的是json库中有load()和loads()两个函数.
- 函数load()作用为读取JSON文件生成Python对象
- 函数loads()作用为读取JSON 字符串流生成Python对象
我们可以将loads()函数中的字符s的含义理解成 load for strings.
3.2. 将JSON文件读取为Pandas类型
当然我们也可以使用Pandas库中的 read_json函数来读取对应的JSON文件,
代码如下:
import pandas as pd
df = pd.read_json('superheroes.json')
运行结果如下:
需要注意的是使用Pandas库不仅仅可以读取电脑本地磁盘上的JSON文件,也可以通过URL读取网络上存放的文件.
代码如下:
df1 = pd.read_json('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json')
3.3. 使用Pandas读取嵌套JSON类型
我们有时候遇到的JSON文件是嵌套的,这经常会让读取工作变得有些困难.
其实嵌套JSON和Python中的嵌套字典思想类似,即字典中嵌套字典.
我们观察上述例子中的member字段,其值也为字典类型,下图中我们使用缩进来展示嵌套结构。
嵌套JSON示例
设想一下,当我们将JSON文件加载到Pandas数据框架中时,members列如下所示。每行包含一个字典。
接下来我们讨论两种实现方法,这两种方法中,我们可以解析数据,以便将每个键分解为单独的一列。
方案一
我们可以在members这一列上使用apply方法,代码如下:
df['members'].apply(pd.Series)
上述代码执行后,members列会被拆分为4个新列,如下所示:
当然如果你想将上述拆分后的结果和之前的结果进行合并,可以使用pd.concat函数,
代码如下:
df = pd.concat([df['members'].apply(pd.Series), df.drop('members', axis = 1)], axis = 1)
方案二
在Pandas库中还有一个函数 json_normalize() ,它允许我们把嵌套的JSON展开。这是最简单的方法来解析嵌套的JSON了。
代码如下:
def test2():
with open('superheroes.json') as f:
superHeroSquad = json.load(f)
out = pd.json_normalize(superHeroSquad, record_path=['members'],
meta=['squadName', 'homeTown', 'formed', 'secretBase', 'active'])
print(out)
上述代码中:
- record_path为我们希望拆分的列的名字
- meta为列名的list,为我们输出的次序
运行结果如下:
最后我们需要注意的是,我们可以在上述函数json_normalize中添加参数 meta_prefix,这样可以让我们对meta中的名字添加统一的前缀。
代码如下:
pd.json_normalize(superHeroSquad,
record_path = ['members'],
meta = ['squadName', 'homeTown', 'formed', 'secretBase', 'active'],
meta_prefix = 'members_')
运行结果如下:
访问特定位置的数据
在Python中我们可以通过Key的名字或者下标来访问JSON文件中任意位置的数据。
比如,假设我们想知道我们的第二个超级英雄的秘密身份。即在下图中,需要访问特定位置的数据在下图中以紫色突出显示。
为了得到这个值,我们可以直接使用以下语句:
superHeroSquad['members'][1]['secretIdentity']
从上图层次结构的顶部开始,由上往下,我们需要的第一个key是'members',因为它是我们需要访问的值所在的父节点。
接着在‘members’对应的键值中,我们看中括号,然后下标1表示list中的第二个成员。接着我们来看字段'secretIdentity', 如下所示:
常见问题:
JSONDecodeError(“Expecting value”, s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
原因:JSON格式不对
解决方式:把大JSON拆成小的,观察下结构。分而治之(JSON文很小就算了,直接看)
zip 多个list后变空
原因:有个list为空
zip会取最短的list合并,如果有个list长度为0,则zip后为0
TypeError: can only concatenate str (not "NoneType") to str
原因:字符串拼接,或者加和时候,有个元素为None类型
解决方案:
def deal_None(content): if content is None: return "" else: return content
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)