【问题标题】:Convert a CSV column to nested field in json将 CSV 列转换为 json 中的嵌套字段
【发布时间】:2020-02-17 11:00:35
【问题描述】:

我有一个 csv 文件,其中一些列的格式为 x;y;z。我正在使用 pandas 读取这些数据,进行一些预处理并使用 pandas 的 to_json/to_dict 方法转换为 json 对象列表。在转换这些特殊列时,该列的 json 对象应采用 {x: {y: {z: value}}} 格式。可能有不同的列,如 x:y:z 和 x:y:a,这两个必须合并到结果记录 json 中的单个对象中,格式为 {x: {y: {z: value1,一个:值2}}}

CSV:

Id,Name,X;Y;Z,X;Y;A,X;B;Z
101,Adam,1,2,3
102,John,4,5,6
103,Sara,7,8,9

输出:

[ 
   { 
      "Id":101,
      "Name":"Adam",
      "X":{ 
         "Y":{ 
            "Z":1,
            "A":2
         },
         "B":{ 
            "Z":3
         }
      }
   },
   { 
      "Id":102,
      "Name":"John",
      "X":{ 
         "Y":{ 
            "Z":4,
            "A":5
         },
         "B":{ 
            "Z":6
         }
      }
   },
   { 
      "Id":103,
      "Name":"Sara",
      "X":{ 
         "Y":{ 
            "Z":7,
            "A":8
         },
         "B":{ 
            "Z":9
         }
      }
   }
]

【问题讨论】:

  • @pissall 我不需要进行分组,因为 x;y;z 是单列,它的值必须转换为嵌套的 json 对象
  • 如果您实际显示您的数据结构和预期输出,您可能会得到更好的响应
  • @ChrisDoyle 更新了数据结构和输出
  • 谢谢,我会看看,但到目前为止你尝试了什么,什么不起作用

标签: python json pandas csv


【解决方案1】:

我发现使用 pandas 将数据转储为 dict 更容易,然后使用递归函数遍历键,在遇到包含 ; 的键的地方,然后我通过此分隔符拆分键并递归创建嵌套的字典。当我到达拆分键中的最后一个元素时,我用原始值更新键并从字典中删除原始键。

import pandas as pd
from io import StringIO
import json

def split_key_to_nested_dict(original_dict, original_key, nested_dict, nested_keys):
    if nested_keys[0] not in nested_dict:
        nested_dict[nested_keys[0]] = {}
    if len(nested_keys) == 1:
        nested_dict[nested_keys[0]] = original_dict[original_key]
        del original_dict[original_key]
    else:
        split_key_to_nested_dict(original_dict, original_key, nested_dict[nested_keys[0]], nested_keys[1:])


csv_data = StringIO("""Id,Name,X;Y;Z,X;Y;A,X;B;Z
101,Adam,1,2,3
102,John,4,5,6
103,Sara,7,8,9""")
df = pd.DataFrame.from_csv(csv_data)
df.insert(0, df.index.name, df.index)
dict_data = df.to_dict('records')

for data in dict_data:
    keys = list(data.keys())
    for key in keys:
        if ';' in key:
            nested_keys = key.split(';')
            split_key_to_nested_dict(data, key, data, nested_keys)
print(json.dumps(dict_data))

输出

[{"Id": 101, "Name": "Adam", "X": {"Y": {"Z": 1, "A": 2}, "B": {"Z": 3}}}, {"Id": 102, "Name": "John", "X": {"Y": {"Z": 4, "A": 5}, "B": {"Z": 6}}}, {"Id": 103, "Name": "Sara", "X": {"Y": {"Z": 7, "A": 8}, "B": {"Z": 9}}}]

格式化输出

[
  {
    "Id": 101,
    "Name": "Adam",
    "X": {
      "Y": {
        "Z": 1,
        "A": 2
      },
      "B": {
        "Z": 3
      }
    }
  },
  {
    "Id": 102,
    "Name": "John",
    "X": {
      "Y": {
        "Z": 4,
        "A": 5
      },
      "B": {
        "Z": 6
      }
    }
  },
  {
    "Id": 103,
    "Name": "Sara",
    "X": {
      "Y": {
        "Z": 7,
        "A": 8
      },
      "B": {
        "Z": 9
      }
    }
  }
]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-07
    • 2020-10-28
    • 2020-04-02
    • 2018-10-27
    • 2021-05-17
    • 2021-01-08
    • 1970-01-01
    相关资源
    最近更新 更多