【问题标题】:Parse nested json to csv using Python Pandas使用 Python Pandas 将嵌套的 json 解析为 csv
【发布时间】:2020-02-21 10:51:54
【问题描述】:

我有一个以下格式的 json:

{"MainName":[{"col1":"12345","col2":"False","col3":"190809","SubName1":{"col4":30.00,"SubName2":{"col5":"19703","col6":"USD"}},"col7":"7372267","SubName3":[{"col8":"345337","col9":"PC"}],"col10":"10265","col11":"29889004","col12":"calculated","col13":"9218","SubName4":{"col14":1,"SubName5":{"col15":"1970324","col16":"integer"}},"col17":"434628","col18":"2020-02-06T13:47:40.000-0800","col19":"754878037","SubName6":{"col20":30.00,"SubName7":{"col21":"19703248","col22":"USD"}}},{"col1":"12345","col2":"False","col3":"190809","SubName1":{"col4":30.00,"SubName2":{"col5":"19703","col6":"USD"}},"col7":"7372267","SubName3":[{"col8":"345337","col9":"PC"}],"col10":"10265","col11":"29889004","col12":"calculated","col13":"9218","SubName4":{"col14":1,"SubName5":{"col15":"1970324","col16":"integer"}},"col17":"434628","col18":"2020-02-06T13:47:40.000-0800","col19":"754878037","SubName6":{"col20":30.00,"SubName7":{"col21":"19703248","col22":"USD"}}}],"skip":0,"top":2,"next":"/v1/APIName?skip=2&top=2"}

我想把它转换成以下格式的csv:

MainName_col1,MainName_col2,MainName_col3,MainName_SubName1_col4,MainName_SubName1_SubName2_col5,MainName_SubName1_SubName2_col6,MainName_col7,MainName_SubName3_col8,MainName_SubName3_col9,MainName_col10,MainName_col11,MainName_col12,MainName_col13,MainName_SubName4_col14,MainName_SubName4_SubName5_col15,MainName_SubName4_SubName5_col16,MainName_col17,MainName_col18,MainName_col19,MainName_SubName6_col20,MainName_SubName6_SubName7_col21,MainName_SubName6_SubName7_col22
12345,False,190809,30.0,19703,USD,7372267,345337,PC,10265,29889004,calculated,9218,1,1970324,integer,434628,2020-02-06T13:47:40.000-0800,754878037,30.0,19703248,USD
12345,False,190809,30.0,19703,USD,7372267,345337,PC,10265,29889004,calculated,9218,2,123453,integer,434628,2020-02-06T13:47:40.000-0800,754878037,30.0,19703248,USD

请帮帮我。

【问题讨论】:

    标签: python json pandas csv


    【解决方案1】:

    使用下面的函数来扁平化你的 JSON 数据。

    dc = {"MainName":[{"col1":"12345","col2":False,"col3":"190809","SubName1":{"col4":30.00,"SubName2":{"col5":"19703","col6":"USD"}},"col7":"7372267","SubName3":[{"col8":"345337","col9":"PC"}],"col10":"10265","col11":"29889004","col12":"calculated","col13":"9218","SubName4":{"col14":1,"SubName5":{"col15":"1970324","col16":"integer"}},"col17":"434628","col18":"2020-02-06T13:47:40.000-0800","col19":"754878037","SubName6":{"col20":30.00,"SubName7":{"col21":"19703248","col22":"USD"}}}],"skip":0,"top":1,"next":"/v1/APIName?skip=1&top=1"}
    def flatten(root: str, dict_obj: dict):
        flat = {}
        for i in dict_obj.keys():
            val = dict_obj[i]
            if not isinstance(val, dict) and not isinstance(val, list):
                flat[f'{root}_{i}'] = val
            else:
                if isinstance(val, list):
                    val = val[-1]
                flat.update(flatten(f'{root}_{i}', val))
        return flat
    flatten('MainName', dc['MainName'][0])
    

    它会给你预期的输出。然后按照你想要的方式使用它。

    {'MainName_col1': '12345',
     'MainName_col2': False,
     'MainName_col3': '190809',
     'MainName_SubName1_col4': 30.0,
     'MainName_SubName1_SubName2_col5': '19703',
     'MainName_SubName1_SubName2_col6': 'USD',
     'MainName_col7': '7372267',
     'MainName_SubName3_col8': '345337',
     'MainName_SubName3_col9': 'PC',
     'MainName_col10': '10265',
     'MainName_col11': '29889004',
     'MainName_col12': 'calculated',
     'MainName_col13': '9218',
     'MainName_SubName4_col14': 1,
     'MainName_SubName4_SubName5_col15': '1970324',
     'MainName_SubName4_SubName5_col16': 'integer',
     'MainName_col17': '434628',
     'MainName_col18': '2020-02-06T13:47:40.000-0800',
     'MainName_col19': '754878037',
     'MainName_SubName6_col20': 30.0,
     'MainName_SubName6_SubName7_col21': '19703248',
     'MainName_SubName6_SubName7_col22': 'USD'}
    

    【讨论】:

    • 如何处理json中的多条记录,到目前为止,即使我们给出多条记录,它也只解析第一条记录?
    • 在按键上循环
    【解决方案2】:

    据我了解,您的 dc 如下所示

    dc = {"MainName":[{"col1":"12345","col2":"False","col3":"190809","SubName1":{"col4":30.00,"SubName2":{"col5":"19703","col6":"USD"}},"col7":"7372267","SubName3":[{"col8":"345337","col9":"PC"}],"col10":"10265","col11":"29889004","col12":"calculated","col13":"9218","SubName4":{"col14":1,"SubName5":{"col15":"1970324","col16":"integer"}},"col17":"434628","col18":"2020-02-06T13:47:40.000-0800","col19":"754878037","SubName6":{"col20":30.00,"SubName7":{"col21":"19703248","col22":"USD"}}},{"col1_a":"12345XX","col2_b":"False","col3_c":"190809","SubName1":{"col4_d":30.00,"SubName2":{"col5_e":"19703","col6_f":"USD"}},"col7_g":"7372267","SubName3":[{"col8_h":"345337","col9":"PC"}],"col10_i":"10265","col11_j":"29889004","col12_k":"calculated","col13_l":"9218","SubName4":{"col14_m":1,"SubName5":{"col15_n":"1970324","col16_o":"integer"}},"col17_p":"434628","col18_q":"2020-02-06T13:47:40.000-0800","col19_r":"754878037","SubName6":{"col20_s":30.00,"SubName7":{"col21_t":"19703248","col22_u":"USDZZ"}}}],"skip":0,"top":2,"next":"/v1/APIName?skip=2&top=2"}
    

    我用上面的答案把所有东西都拼成了一个对象

    def flatten(root: str, dict_obj: dict):
        flat = {}
        for i in dict_obj.keys():
            val = dict_obj[i]
            if not isinstance(val, dict) and not isinstance(val, list):
                flat[f'{root}_{i}'] = val
            else:
                if isinstance(val, list):
                    val = val[-1]
                flat.update(flatten(f'{root}_{i}', val))
        return flat
    
    keys_list  = []
    values_list = []
    for i in range(len(dc['MainName'])):  
      result = flatten('MainName', dc['MainName'][i])
      keys_list.append(list(result.keys()))
      values_list.append(list(result.values()))
    
    for k in keys_list:
        for res in k:
          guestFile = open("sample.csv","a")
          guestFile.write(res)
          guestFile.write(",")
          guestFile.close()
    
    for v in values_list:
        for res in v:
          guestFile = open("sample.csv","a")
          guestFile.write(str(res))
          guestFile.write(",")
          guestFile.close()
    

    查看我的代码athttps://repl.it/@TamilselvanLaks/jsontocsvmul

    Note: Use the 'run' button to run the program, left side you can see sample.csv 
    
    there you can see all keys as like you want 
    

    请告诉我我的回答符合您的期望

    【讨论】:

    • json 只有 MainName,然后它的记录范围从 col1 到 col22,这些值用逗号分隔。我尝试为 10 条记录运行您的代码,但它生成了错误说明: Traceback (most recent call last): File "", line 3, in File "", line 5, in flatten TypeError : isinstance() arg 2 必须是类型或类型的元组
    • 你试过我分享的链接了吗?请分享您的 dc 和预期的 csv 格式
    • 我在 json 中又添加了一条记录,并根据需要编辑了输出
    • 您要实现的目标是 {'MainName_col1': '12345', 'MainName_col1': '12345'} 这在不允许键的字典重复中是不可能的。据我所知,您有 2 个选择 1)将这 2 个作为单独的数组移动,即维护 MainName1、MainNam2 Choice2)您的 CSV 应该有一个记录索引,如 MainName_0_col1、MainName_1_col1、12345、12345}
    • 这只是一个示例记录,我添加它只是为了阐明多于 1 条记录的 json 将如何保存。 json中不会有重复记录。
    猜你喜欢
    • 2018-05-29
    • 2021-08-31
    • 2017-06-10
    • 2017-03-01
    • 2019-05-05
    • 2020-10-08
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多