【问题标题】:Transform pandas DataFrame to json and add new keys将 pandas DataFrame 转换为 json 并添加新键
【发布时间】:2021-08-15 01:10:35
【问题描述】:

我不知道如何正确表达这一点,所以我将尝试用一个可复制的例子来解释这一点。

pandas.DataFrame 对象中有数千个条目。我想将每一行导出为自己的 json 文件,其中包含一些在数据框结构中未明确可用的键。

我的数据框df 如下所示:

> df = pd.DataFrame({'ID':['0','1','2'],
                     'NAME':['jimmy','james','joben'],
                     'LAST':['neutron','baxter','segel'],
                     'ADDRESS':['101 ocean avenue','202 bubble gum county','303 china town'],
                     'COUNTY':['yellow card park','candy kingdom','universal studio']})
ID NAME LAST ADDRESS COUNTY
0 jimmy neutron 101 ocean avenue yellow card park
1 james baxter 202 bubble gum county candy kingdom
2 joben segel 303 china town universal studio

我想将每一行转换为具有以下结构的 json 文件:

  • 'ID'
  • “个人”,包含NAMELAST
  • 'GEO',包含 ADDRESSCOUNTY

换句话说,我希望第一个转换后的行如下所示:

{
    'ID':'0',
    'PERSONAL':
        {
            'NAME':'jimmy',
            'LAST':'neutron'
        },
    'GEO':
        {
            'ADDRESS':'101 ocean avenue',
            'COUNTY':'yellow card park'
        }
}

我正在考虑将df 转换为pandas.MultiIndex 结构以添加PERSONALGEO 索引,然后使用pandas.DataFrame.to_json 导出每一行。但是,我不确定这是否可行,并想在尝试之前询问一下。

【问题讨论】:

    标签: python json pandas dataframe


    【解决方案1】:

    根据here@Parsa T 提供的函数,您只需更改列名并使用该函数即可获得所需的结果。

    def set_for_keys(my_dict, key_arr, val):
        """
        Set value at the path in my_dict defined by the string (or serializable object) array key_arr
        """
        current = my_dict
        for i in range(len(key_arr)):
            key = key_arr[i]
            if key not in current:
                current[key] = val if i==len(key_arr)-1 else {}
            else:
                if type(current[key]) is not dict:
                    print("Given dictionary is not compatible with key structure requested")
                    raise ValueError("Dictionary key already occupied")
    
            current = current[key]
    
        return my_dict
    
    def to_formatted_json(df, sep="."):
        result = []
        for _, row in df.iterrows():
            parsed_row = {}
            for idx, val in row.iteritems():
                keys = idx.split(sep)
                parsed_row = set_for_keys(parsed_row, keys, val)
    
            result.append(parsed_row)
        return result
    
    
    df.columns = ['ID', 'PERSONAL.NAME', 'PERSONAL.LAST', 'GEO.ADDRESS', 'GEO.COUNTY']
    #Where df was parsed from json-dict using json_normalize
    print(to_formatted_json(df, sep="."))
    
    

    输出:

    [{'ID': '0',
      'PERSONAL': {'NAME': 'jimmy', 'LAST': 'neutron'},
      'GEO': {'ADDRESS': '101 ocean avenue', 'COUNTY': 'yellow card park'}},
     {'ID': '1',
      'PERSONAL': {'NAME': 'james', 'LAST': 'baxter'},
      'GEO': {'ADDRESS': '202 bubble gum county', 'COUNTY': 'candy kingdom'}},
     {'ID': '2',
      'PERSONAL': {'NAME': 'joben', 'LAST': 'segel'},
      'GEO': {'ADDRESS': '303 china town', 'COUNTY': 'universal studio'}}]
    

    【讨论】:

      【解决方案2】:

      Pandas 开箱即用。

      pandas.DataFrame.to_json

      这里是示例数据框:

      import json
      df = pd.DataFrame(
          [["a", "b"], ["c", "d"]],
          index=["row 1", "row 2"],
          columns=["col 1", "col 2"],
      )
      

      这是使用to_json()的结果:

      result = df.to_json(orient="split")
      parsed = json.loads(result)
      json.dumps(parsed, indent=4)  
      {
          "columns": [
              "col 1",
              "col 2"
          ],
          "index": [
              "row 1",
              "row 2"
          ],
          "data": [
              [
                  "a",
                  "b"
              ],
              [
                  "c",
                  "d"
              ]
          ]
      }
      

      这里是链接: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_json.html

      【讨论】:

      • 我对此表示赞同,因为我很欣赏这种努力。但是,我对如何将to_json 应用于我的问题感到困惑。您的示例将列名作为其自己的键,而不是设置新键(个人和地理)并将某些列分配给每个键。你能扩展一下吗?
      • 从下面的下一个答案看来,它已经为您完成了。但是,您只需将列名columns= 替换为您自己的列标题,并将表中的数据替换为您自己的数据。 df.columns = ['ID', 'PERSONAL.NAME', 'PERSONAL.LAST', 'GEO.ADDRESS', 'GEO.COUNTY']
      猜你喜欢
      • 2017-04-13
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 2017-01-08
      • 2023-03-31
      • 1970-01-01
      相关资源
      最近更新 更多