嵌套 JSON 秒变 Dataframe!

简介: 嵌套 JSON 秒变 Dataframe!

调用API和文档数据库会返回嵌套的JSON对象,当我们使用Python尝试将嵌套结构中的键转换为列时,数据加载到pandas中往往会得到如下结果:

df = pd.DataFrame.from_records(results [“ issues”],columns = [“ key”,“ fields”])

微信图片_20220218211146.jpg

说明:这里results是一个大的字典,issues是results其中的一个键,issues的值为一个嵌套JSON对象字典的列表,后面会看到JSON嵌套结构。


问题在于API返回了嵌套的JSON结构,而我们关心的键在对象中确处于不同级别。


嵌套的JSON结构张成这样的。


微信图片_20220218211211.jpg

而我们想要的是下面这样的。

微信图片_20220218211225.jpgimage.gif

下面以一个API返回的数据为例,API通常包含有关字段的元数据。假设下面这些是我们想要的字段。

  • key:JSON密钥,在第一级的位置。
  • summary:第二级的“字段”对象。
  • status name:第三级位置。
  • statusCategory name:位于第4个嵌套级别。


如上,我们选择要提取的字段在issues列表内的JSON结构中分别处于4个不同的嵌套级别,一环扣一环。


{
  "expand": "schema,names",
  "issues": [
    {
      "fields": {
        "issuetype": {
          "avatarId": 10300,
          "description": "",
          "id": "10005",
          "name": "New Feature",
          "subtask": False
        },
        "status": {
          "description": "A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.",
          "id": "5",
          "name": "Resolved",
          "statusCategory": {
            "colorName": "green",
            "id": 3,
            "key": "done",
            "name": "Done",
          }
        },
        "summary": "Recovered data collection Defraglar $MFT problem"
      },
      "id": "11861",
      "key": "CAE-160",
    },
    {
      "fields": { 
... more issues],
  "maxResults": 5,
  "startAt": 0,
  "total": 160
}

一个不太好的解决方案


一种选择是直接撸码,写一个查找特定字段的函数,但问题是必须对每个嵌套字段调用此函数,然后再调用.apply到DataFrame中的新列。

为获取我们想要的几个字段,首先我们提取fields键内的对象至列:

df = (
    df["fields"]
    .apply(pd.Series)
    .merge(df, left_index=True, right_index = True)
)

微信图片_20220218211302.jpg


从上表看出,只有summary是可用的,issuetype、status等仍然埋在嵌套对象中。


下面是提取issuetype中的name的一种方法。

# 提取issue type的name到一个新列叫"issue_type"
df_issue_type = (
    df["issuetype"]
    .apply(pd.Series)
    .rename(columns={"name": "issue_type_name"})["issue_type_name"]
)
df = df.assign(issue_type_name = df_issue_type)

image.gif像上面这样,如果嵌套层级特别多,就需要自己手撸一个递归来实现了,因为每层嵌套都需要调用一个像上面解析并添加到新列的方法。

对于编程基础薄弱的朋友,手撸一个其实还挺麻烦的,尤其是对于数据分析师,着急想用数据的时候,希望可以快速拿到结构化的数据进行分析。

下面东哥分享一个pandas的内置解决方案。


内置的解决方案


pandas中有一个牛逼的内置功能叫 .json_normalize。


pandas的文档中提到:将半结构化JSON数据规范化为平面表。


前面方案的所有代码,用这个内置功能仅需要3行就可搞定。步骤很简单,懂了下面几个用法即可。

  • 确定我们要想的字段,使用 . 符号连接嵌套对象。
  • 将想要处理的嵌套列表(这里是results["issues"])作为参数放进 .json_normalize 中。
  • 过滤我们定义的FIELDS列表。
FIELDS = ["key", "fields.summary", "fields.issuetype.name", "fields.status.name", "fields.status.statusCategory.name"]
df = pd.json_normalize(results["issues"])
df[FIELDS]

微信图片_20220218211329.jpgimage.gif

没错,就这么简单。


其它操作

记录路径


除了像上面那样传递results["issues"]列表之外,我们还使用record_path参数在JSON对象中指定列表的路径。

# 使用路径而不是直接用results["issues"]
pd.json_normalize(results, record_path="issues")[FIELDS]


自定义分隔符

还可以使用sep参数自定义嵌套结构连接的分隔符,比如下面将默认的“.”替换“-

# 用 "-" 替换默认的 "."
FIELDS = ["key", "fields-summary", "fields-issuetype-name", "fields-status-name", "fields-status-statusCategory-name"]
pd.json_normalize(results["issues"], sep = "-")[FIELDS]


控制递归


如果不想递归到每个子对象,可以使用max_level参数控制深度。在这种情况下,由于statusCategory.name字段位于JSON对象的第4级,因此不会包含在结果DataFrame中。

# 只深入到嵌套第二级
pd.json_normalize(results, record_path="issues", max_level = 2)

下面是.json_normalize的pandas官方文档说明,如有不明白可自行学习,本次东哥就介绍到这里。


pandas官方文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.json_normalize.html

相关文章
|
6月前
|
存储 JSON 数据处理
从JSON数据到Pandas DataFrame:如何解析出所需字段
从JSON数据到Pandas DataFrame:如何解析出所需字段
405 1
|
3月前
|
JSON Java 数据格式
Java系列之:如何取出嵌套JSON中的数据值
这篇文章介绍了如何在Java中取出嵌套JSON数据值的方法,通过使用`JSONObject`类及其`getJSONObject`和`get`方法来逐步解析和提取所需的数据。
Java系列之:如何取出嵌套JSON中的数据值
|
JSON 数据可视化 数据挖掘
python数据可视化开发(2):pandas读取Excel的数据格式处理(数据读取、指定列数据、DataFrame转json、数学运算、透视表运算输出)
python数据可视化开发(2):pandas读取Excel的数据格式处理(数据读取、指定列数据、DataFrame转json、数学运算、透视表运算输出)
375 0
|
4月前
|
JSON 分布式计算 大数据
MaxCompute产品使用合集之如何解析嵌套的JSON数据
MaxCompute作为一款全面的大数据处理平台,广泛应用于各类大数据分析、数据挖掘、BI及机器学习场景。掌握其核心功能、熟练操作流程、遵循最佳实践,可以帮助用户高效、安全地管理和利用海量数据。以下是一个关于MaxCompute产品使用的合集,涵盖了其核心功能、应用场景、操作流程以及最佳实践等内容。
182 0
|
5月前
|
JSON Go 数据格式
技术经验分享:Golang如何解组嵌套的JSON数据的子集
技术经验分享:Golang如何解组嵌套的JSON数据的子集
|
5月前
|
JSON Go 数据格式
【golang】json数据解析 - 嵌套json解析
【golang】json数据解析 - 嵌套json解析
74 0
|
6月前
|
SQL JSON Apache
Flink问题之嵌套 json 中string 数组的解析异常如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
306 1
|
6月前
|
JSON 数据挖掘 数据处理
在Python如何将 JSON 转换为 Pandas DataFrame?
在Python如何将 JSON 转换为 Pandas DataFrame?
56 1
|
JSON 人工智能 前端开发
前端多重嵌套的json数据格式解析
解决方法 1.解析数据格式 ,这里需要注意的是return,要把次条数据格式放在获取api接口的最后一项,否则不会执行 循环只返回return所返回的值,并不会执行下面的值
235 0
前端多重嵌套的json数据格式解析
|
JSON 数据格式
layui框架实战案例(3):使用多层嵌套json格式数据的使用templet解决方案
layui框架实战案例(3):使用多层嵌套json格式数据的使用templet解决方案
273 0