【问题标题】:Flatten Nested JSON in Python在 Python 中展平嵌套的 JSON
【发布时间】:2022-06-21 16:36:03
【问题描述】:

我是 Python 新手,我很困惑(我已经浏览了多个其他 stackoverflow 和其他网站,但仍然无法使其正常工作)。

我有以下来自 API 连接的 json

    {
   "results":[
      {
         "group":{
            "mediaType":"chat",
            "queueId":"67d9fb5e-26b2-4db5-b062-bbcfa8d2ca0d"
         },
         "data":[
            {
               "interval":"2021-01-14T13:12:19.000Z/2022-01-14T13:12:19.000Z",
               "metrics":[
                  {
                     "metric":"nOffered",
                     "qualifier":null,
                     "stats":{
                        "max":null,
                        "min":null,
                        "count":14,
                        "count_negative":null,
                        "count_positive":null,
                        "sum":null,
                        "current":null,
                        "ratio":null,
                        "numerator":null,
                        "denominator":null,
                        "target":null
                     }
                  }
               ],
               "views":null
            }
         ]
      }
   ]
}

而我主要想摆脱的是(或至少是类似的东西)

MediaType QueueId NOffered
Chat 67d9fb5e-26b2-4db5-b062-bbcfa8d2ca0d 14

这样的事情可能吗?我已经尝试了多种方法,我要么在一行中将所有内容全部搞定,要么只是得到不同的错误。

【问题讨论】:

  • 向我们展示您尝试了什么以及遇到了什么错误!
  • 试过 a_json = json.loads(data_query_result) dataframe = pd.DataFrame.from_dict(a_json, orient="index") df = pd.json_normalize(dataframe) print (df) 这只是给了我一个空数据框。如果我尝试将 data_query_result 直接传递给 json_normalize 我会收到一条错误消息 # check to see if a simple recursive function is possible to NotImplementedError: Other attempt I've got String Indices must be integers error
  • 今天早些时候也试过这个towardsdatascience.com/…

标签: python


【解决方案1】:

您得到的错误表明您错过了某些值实际上是数组中的字典。

假设您想要展平您的 json 文件以检索以下键:mediaTypequeueIdcount

这些可以通过以下示例代码检索:

import json
with open(path_to_json_file, 'r') as f:
    json_dict = json.load(f)

for result in json_dict.get("results"):
    media_type = result.get("group").get("mediaType")
    queue_id = result.get("group").get("queueId")
    n_offered = result.get("data")[0].get("metrics")[0].get("count") 

如果您的 datametrics 键有多个索引,您将不得不使用 for 循环相应地检索每个 count 值。

【讨论】:

  • 完美,这对我有用。必须将其更改为 s = json_dict d = json.loads(s) 以获得 d.get("results") 中的结果: media_type = results.get("group").get("mediaType") queue_id = results.get ("group").get("queueId") n_offered = results.get("data")[0].get("metrics")[0].get("stats").get("count")
【解决方案2】:

假设 API 响应的格式始终相同,您是否考虑过硬编码提取所需的数据?

这应该可以工作:将response 定义为 API 输出:

response =     {
   "results":[
      {
          "group":{
            "mediaType":"chat",
            "queueId":"67d9fb5e-26b2-4db5-b062-bbcfa8d2ca0d"
          },
          "data":[
            {
               "interval":"2021-01-14T13:12:19.000Z/2022-01-14T13:12:19.000Z",
               "metrics":[
                  {
                     "metric":"nOffered",
                     "qualifier":'null',
                     "stats":{
                        "max":'null',
                        "min":'null',
                        "count":14,
                        "count_negative":'null',
                        "count_positive":'null',
                        "sum":'null',
                        "current":'null',
                        "ratio":'null',
                        "numerator":'null',
                        "denominator":'null',
                        "target":'null'
                     }
                  }
               ],
               "views":'null'
            }
         ]
      }
   ]
}

您可以按如下方式提取结果:

results = response["results"][0]

{
    "mediaType": results["group"]["mediaType"],
    "queueId": results["group"]["queueId"],
    "nOffered": results["data"][0]["metrics"][0]["stats"]["count"]
}

给了

{
    'mediaType': 'chat',
    'queueId': '67d9fb5e-26b2-4db5-b062-bbcfa8d2ca0d',
    'nOffered': 14
}

【讨论】:

  • 这在我测试时有效,但对于我正在尝试做的事情无法扩展,因此与其他解决方案一起使用。谢谢
【解决方案3】:
import pandas as pd
tree=     {
   "results":[
      {
         "group":{
            "mediaType":"chat",
            "queueId":"67d9fb5e-26b2-4db5-b062-bbcfa8d2ca0d"
         },
         "data":[
            {
               "interval":"2021-01-14T13:12:19.000Z/2022-01-14T13:12:19.000Z",
               "metrics":[
                  {
                     "metric":"nOffered",
                     "qualifier":"null",
                     "stats":{
                        "max":"null",
                        "min":"null",
                        "count":14,
                        "count_negative":"null",
                        "count_positive":"null",
                        "sum":"null",
                        "current":"null",
                        "ratio":"null",
                        "numerator":"null",
                        "denominator":"null",
                        "target":"null"
                     }
                  }
               ],
               "views":"null"
            }
         ]
      }
   ]
}


def traverse_parser_dfs(master_tree):
  flatten_tree_node = []
  def _process_leaves(tree:dict,prefix:str = "node", tree_node:dict = dict(), update:bool = True):
      is_nested = False
      if isinstance(tree,dict):
        for k in tree.keys():
            if type(tree[k]) == str:
                colName = prefix + "_" + k
                tree_node[colName] = tree[k]
            elif type(tree[k]) == dict:
                prefix += "_" + k
                leave = tree[k]
                _process_leaves(leave,prefix = prefix, tree_node = tree_node, update = False)
        for k in tree.keys():
            if type(tree[k]) == list:
                is_nested = True
                prefix += "_" + k
                for leave in tree[k]:
                    _process_leaves(leave,prefix = prefix, tree_node = tree_node.copy())
        if not is_nested and update:
            flatten_tree_node.append(tree_node)
        
  _process_leaves(master_tree)
  df = pd.DataFrame(flatten_tree_node)
  df.columns = df.columns.str.replace("@", "_")
  df.columns = df.columns.str.replace("#", "_")
  return df


print(traverse_parser_dfs(tree))


  node_results_group_mediaType  ... node_results_group_data_metrics_stats_target
0                         chat  ...                                         null

[1 rows x 16 columns]

【讨论】:

    猜你喜欢
    • 2021-02-06
    • 2019-12-22
    • 2021-12-20
    • 2020-12-15
    • 2020-06-10
    • 1970-01-01
    • 2016-10-06
    • 2021-09-05
    • 1970-01-01
    相关资源
    最近更新 更多