【问题标题】:JSON Normalize On Extremely Nested JSON Data Structure极度嵌套的 JSON 数据结构上的 JSON 规范化
【发布时间】:2018-08-14 22:53:51
【问题描述】:

我有以下 JSON 数据结构。我正在尝试将其放入 Pandas DataFrame。

pandas.io.json json_normalize 工作正常,除了“tunnels-in”和“tunnels-out”部分。这些是其中包含一些嵌套字典的列表。我已经尝试了我见过的几乎所有格式的 json_normalize 示例,但都没有成功。关于我能得到的工作如下。

json_normalize(json_dict['data']['viptela-oper-vpn']['dpi']['flows'])

只要我添加变量来定义额外的结构,我就无法克服错误。我研究了其他方法来做到这一点 - 记录在这里 - 这似乎确实有效,但它似乎没有处理任何垂直结构的概念。在这里,我们有一个流列表-我想将每个流展平为单独的列-其中每个流的值位于同一列的不同行中

https://towardsdatascience.com/flattening-json-objects-in-python-f5343c794b10

有谁知道使用 normalize 函数的方法,同时保留字典的嵌套列表?如您所见,并非每个流都有隧道输入/隧道输出。这是我自己试图将其弄平的另一个复杂因素。

非常感谢任何想法。

非常感谢,

数据结构

{
  "data": {
    "viptela-oper-vpn": {
      "dpi": {
        "flows": [
          {
            "vpn-id": 1,
            "src-ip": "1.1.0.200",
            "dst-ip": "1.3.0.200",
            "src-port": 65369,
            "dst-port": 1967,
            "proto": "udp",
            "application": "udp",
            "family": "Network Service",
            "active-since": "2018-02-28T22:51:54+00:00",
            "packets": 2,
            "octets": 132,
            "tunnels-in": [
              {
                "index_me": 1,
                "local-tloc": {
                  "ip": "1.1.1.104",
                  "color": "private2",
                  "encap": "ipsec"
                },
                "remote-tloc": {
                  "ip": "1.1.1.103",
                  "color": "private2",
                  "encap": "ipsec"
                },
                "packets": 1,
                "octets": 80,
                "start-time": "2018-02-28T22:51:54+00:00"
              }
            ],
            "tunnels-out": [
              {
                "index_me": 1,
                "local-tloc": {
                  "ip": "1.1.1.104",
                  "color": "private2",
                  "encap": "ipsec"
                },
                "remote-tloc": {
                  "ip": "1.1.1.103",
                  "color": "mpls",
                  "encap": "ipsec"
                },
                "packets": 1,
                "octets": 52,
                "start-time": "2018-02-28T22:51:54+00:00"
              }
            ]
          },
          {
            "vpn-id": 1,
            "src-ip": "1.1.0.200",
            "dst-ip": "1.3.0.200",
            "src-port": 65529,
            "dst-port": 1967,
            "proto": "udp",
            "application": "udp",
            "family": "Network Service",
            "active-since": "2018-02-28T22:52:03+00:00",
            "packets": 2,
            "octets": 132,
            "tunnels-in": [
              {
                "index_me": 1,
                "local-tloc": {
                  "ip": "1.1.1.104",
                  "color": "private2",
                  "encap": "ipsec"
                },
                "remote-tloc": {
                  "ip": "1.1.1.103",
                  "color": "private2",
                  "encap": "ipsec"
                },
                "packets": 1,
                "octets": 80,
                "start-time": "2018-02-28T22:52:03+00:00"
              }
            ],
            "tunnels-out": [
              {
                "index_me": 1,
                "local-tloc": {
                  "ip": "1.1.1.104",
                  "color": "private2",
                  "encap": "ipsec"
                },
                "remote-tloc": {
                  "ip": "1.1.1.103",
                  "color": "mpls",
                  "encap": "ipsec"
                },
                "packets": 1,
                "octets": 52,
                "start-time": "2018-02-28T22:52:03+00:00"
              }
            ]
          },
          {
            "vpn-id": 512,
            "src-ip": "69.26.45.133",
            "dst-ip": "198.19.200.2",
            "src-port": 11895,
            "dst-port": 22,
            "proto": "tcp",
            "application": "ssh",
            "family": "Encrypted",
            "active-since": "2018-02-28T22:42:15+00:00",
            "packets": 1498,
            "octets": 797954
          },
          {
            "vpn-id": 512,
            "src-ip": "198.19.200.2",
            "dst-ip": "69.26.45.139",
            "src-port": 514,
            "dst-port": 514,
            "proto": "udp",
            "application": "syslog",
            "family": "Application Service",
            "active-since": "2018-02-28T22:50:59+00:00",
            "packets": 8,
            "octets": 2820
          }
        ]
      }
    }
  }
}

目前的功能

def myprint(file):
    file_var = ''
    with open(file) as f:
        file_var = f.read()
    extract_json_dict = re.compile('(\\n{\\n)(.*)(\\n}\\n)', re.DOTALL)
    json_string = extract_json_dict.search(file_var).group(0)
    json_dict = json.loads(json_string)
    df = json_normalize(json_dict['data']['viptela-oper-vpn']['dpi']['flows'])

现在显示的列

['active-since', 'application', 'dst-ip', 'dst-port', 'family', 'octets', '数据包','proto','src-ip','src-port','tunnels-in','tunnels-out', 'vpn-id']

除了上面显示的列之外,我还想添加列

本质上,将具有列表作为值的那两列“展平”为附加列,并将每个流的值放在唯一的行中。

['tunnels-in_index_me', '隧道-in_remote-tloc_ip', '隧道-in_remote-tloc_color', '隧道-in_remote-tloc_encap', 'tunnels-out_remote-tloc_ip']

2018 年 3 月 8 日更新

对于其中包含字典列表的列,这似乎符合我的要求。但它需要流号的 [0] 标识符。不确定是否有人知道一种方法可以使其适用于所有流程 - 一次不是一个。如果可以做到这一点,我应该能够根据索引号进行连接或合并。使用单个 json_normalize 行来完成整个事情会更好——但除了 [0] 的问题之外,这似乎还有一个额外的问题,即并非所有流号都有嵌套的字典列表。我会继续尝试这个,但任何想法都值得赞赏。

json_normalize(json_dict['data']['viptela-oper-vpn']['dpi']['flows'][0]['tunnels-in'])

【问题讨论】:

    标签: python json pandas


    【解决方案1】:

    我现在正在努力解决这个问题。通过将索引[0] 问题拉出到另一个pandas.dataframe 中,我绕过了该选择。因此:

    df = json_normalize(pd.DataFrame(list(json_dict['data']['viptela-oper-vpn']['dpi']['flows']))['tunnels-in'])
    

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 2019-12-22
      • 2021-12-12
      • 2020-03-05
      • 2020-06-21
      • 2017-10-27
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      相关资源
      最近更新 更多