猿问

将嵌套 json 读取到数据框中

我有一个json从 Firebase 导出的文件,如下所示。


{

  "reports" : {

    "Google-Pixel 2 XL" : {

      "-MIoCtD9YUF2G9Esfrfz" : {

        "message" : "04 Oct 2020 23:25:17:047 onCreate MainActivity",

        "timestamp" : 1601825117067

      },

      "-MIoCtFVOxu8wdEHtm6q" : {

        "message" : "04 Oct 2020 23:25:17:214 onCreate Service",

        "timestamp" : 1601825117216

      },

      "-MIoCyBtKMQqQzUHEXsW" : {

        "message" : "04 Oct 2020 23:25:37:682 onStartCommand Service",

        "timestamp" : 1601825137685

      },

      "-MIoFWll9r3qwzWNoGMn" : {

        "message" : "04 Oct 2020 23:36:47:687: (1.3212517, 103.860314)",

        "timestamp" : 1601825807693

      }

    },

    "Vivo 1820" : {

      "-MIoF14JUm6JMZrOzDlL" : {

        "message" : "04 Oct 2020 23:34:37:623 onCreate MainActivity",

        "timestamp" : 1601825677653

      },

      "-MIoF1A9ZZNqTu5W-rQD" : {

        "message" : "04 Oct 2020 23:34:38:016 onCreate Service",

        "timestamp" : 1601825678026

      },

      "-MIoF2gNDua9FfLBTg6q" : {

        "message" : "04 Oct 2020 23:34:44:235 onCreate MainActivity",

        "timestamp" : 1601825684248

      }

    }

  }

}

我正在尝试将其转换为 4 列数据框,如下所示


model             | id                   | message                               | timestamp

Google-Pixel 2 XL | -MIoCtD9YUF2G9Esfrfz | 04 Oct 2020 23:25:17:047 onCreate...  | 1601825117067

Vivo 1820         | -MIoF14JUm6JMZrOzDlL | 04 Oct 2020 23:34:37:623 onCreate...  | 1601825677653

我怎么做?我尝试了各种方法和标准化,但似乎无法得到它。


data = pd.read_json("firebase-file.json")

df = pd.json_normalize(data, record_path="reports")

谢谢。


ibeautiful
浏览 128回答 3
3回答

慕容708150

我认为你需要自己压平它,好在它并不复杂:s = [[k, i, *j.values()] for k,v in data["reports"].items() for i, j in v.items()]print (pd.DataFrame(s))                   0                     1                                                  2              30  Google-Pixel 2 XL  -MIoCtD9YUF2G9Esfrfz     04 Oct 2020 23:25:17:047 onCreate MainActivity  16018251170671  Google-Pixel 2 XL  -MIoCtFVOxu8wdEHtm6q          04 Oct 2020 23:25:17:214 onCreate Service  16018251172162  Google-Pixel 2 XL  -MIoCyBtKMQqQzUHEXsW    04 Oct 2020 23:25:37:682 onStartCommand Service  16018251376853  Google-Pixel 2 XL  -MIoFWll9r3qwzWNoGMn  04 Oct 2020 23:36:47:687: (1.3212517, 103.860314)  16018258076934          Vivo 1820  -MIoF14JUm6JMZrOzDlL     04 Oct 2020 23:34:37:623 onCreate MainActivity  16018256776535          Vivo 1820  -MIoF1A9ZZNqTu5W-rQD          04 Oct 2020 23:34:38:016 onCreate Service  16018256780266          Vivo 1820  -MIoF2gNDua9FfLBTg6q     04 Oct 2020 23:34:44:235 onCreate MainActivity  1601825684248分享

慕姐4208626

根据 的官方文档,pd.json_normalize()它假设一个数组(列表)输入。然而,原始的 json 远非字典列表之类的东西,最重要的是,键“id”不存在。因此我认为绝对需要一个手工制作的解析器。代码:import pandas as pdimport jsonfile_path = "/mnt/ramdisk/in.json"with open(file_path) as f:    dic = json.load(f)# discard the redundant "report" layerdic = dic["reports"]# produce a flattened list of dictls = []for k1, v1 in dic.items():    # k1 = model    for k2, v2 in v1.items():        # k2 = the hash-like id        v2["model"] = k1        v2["id"] = k2        ls.append(v2)df = pd.json_normalize(ls)输出# Trim the message for printing purposedf2 = df.copy()df2["message"] = df["message"].apply(lambda s: s[:10])df2Out[28]:       message      timestamp              model                    id0  04 Oct 202  1601825117067  Google-Pixel 2 XL  -MIoCtD9YUF2G9Esfrfz1  04 Oct 202  1601825117216  Google-Pixel 2 XL  -MIoCtFVOxu8wdEHtm6q2  04 Oct 202  1601825137685  Google-Pixel 2 XL  -MIoCyBtKMQqQzUHEXsW3  04 Oct 202  1601825807693  Google-Pixel 2 XL  -MIoFWll9r3qwzWNoGMn4  04 Oct 202  1601825677653          Vivo 1820  -MIoF14JUm6JMZrOzDlL5  04 Oct 202  1601825678026          Vivo 1820  -MIoF1A9ZZNqTu5W-rQD6  04 Oct 202  1601825684248          Vivo 1820  -MIoF2gNDua9FfLBTg6q注意:深入到类哈希id所在的层似乎是有必要的。这是因为最初id是keys,但似乎必须重新格式化它们才能values正确解释为值pd.json_normalize。我在互联网上的简单调查也没有找到使用简单的内置方法来解析这种递归结构的示例。

函数式编程

尝试一下这个(参见我上面的评论)import pandas as pddata = []for k, v in test['reports'].items():    model_name = k    for model in v.items():        _data = {}        _data['model'] = model_name        _data['id'] = model[0]        _data['message'] = model[1]['message']        _data['timestamp'] = model[1]['timestamp']        data.append(_data)df = pd.DataFrame(data)test你的数据在哪里,从而test['reports']访问你想要解析的嵌套信息
随时随地看视频慕课网APP

相关分类

Python
我要回答