将 Pandas Dataframe 转换为表记录的嵌套 JSON

Posted

技术标签:

【中文标题】将 Pandas Dataframe 转换为表记录的嵌套 JSON【英文标题】:Convert Pandas Dataframe to nested JSON for table records 【发布时间】:2021-12-09 15:44:46 【问题描述】:

我正在使用 Python 和 Pandas。尝试将 Pandas 数据框转换为嵌套的 JSON。 .to_json() 函数没有为我的目标提供足够的灵活性。

以下是数据框的一些数据点(CSV,逗号分隔):

Hotel_id,Room_id,Client_id,Loayalty_level,Price

1,100,1,Default,100
1,100,2,Default,98
1,101,1,Default,200
1,101,1,Discounted,196
1,101,2,Default,202
1,101,3,Default,204

有很多重复的信息,我想要一个这样的JSON:


  "hotelId": 1,
  "rooms": [
    
      "roomId": 100,
      "prices": [
        
          "clientId": 1,
          "price": 
            "default": 100
          
        ,
        
          "clientId": 2,
          "price": 
            "default": 98
          
        
      ]
    ,
    
      "roomId": 101,
      "prices": [
        
          "clientId": 1,
          "price": 
            "default": 200,
            "discounted": 196
          
        ,
        
          "clientId": 2,
          "price": 
            "default": 202
          
        ,
        
          "clientId": 3,
          "price": 
            "default": 204
          
        
      ]
    
  ]

如何做到这一点?

【问题讨论】:

你尝试做什么?分享你的代码 如果可能的话,我建议不要使用您的预期输出。 JSON 模式真的很难解析和过滤。想象一下,您获得了 JSON 并且必须转换为数据框。 【参考方案1】:

看看convtools库,它提供了很多数据处理的原语。 这是您的情况的解决方案:

import json

from convtools import conversion as c
from convtools.contrib.tables import Table


input_data = [
    ("Hotel_id", "Room_id", "Client_id", "Loayalty_level", "Price"),
    ("1", "100", "1", "Default", "100"),
    ("1", "100", "2", "Default", "98"),
    ("1", "101", "1", "Default", "200"),
    ("1", "101", "1", "Discounted", "196"),
    ("1", "101", "2", "Default", "202"),
    ("1", "101", "3", "Default", "204"),
]

# if reading from csv is needed
# rows = Table.from_csv("tmp/input.csv", header=True).into_iter_rows(tuple)

# convert to list of dicts
rows = list(Table.from_rows(input_data, header=True).into_iter_rows(dict))

# generate the converter (store somewhere and reuse, because this is where
# code-generation happens)
converter = (
    c.group_by(c.item("Hotel_id"))
    .aggregate(
        
            "hotelId": c.item("Hotel_id").as_type(int),
            "rooms": c.ReduceFuncs.Array(c.this()).pipe(

                c.group_by(c.item("Room_id")).aggregate(
                    
                        "roomId": c.item("Room_id").as_type(int),
                        "prices": c.ReduceFuncs.Array(c.this()).pipe(

                            c.group_by(c.item("Client_id")).aggregate(
                                
                                    "clientId": c.item("Client_id").as_type(
                                        int
                                    ),
                                    "price": c.ReduceFuncs.DictFirst(
                                        c.item("Loayalty_level"),
                                        c.item("Price").as_type(float),
                                    ),
                                
                            )
                        ),
                    
                )
            ),
        
    )
    .gen_converter()
)

print(json.dumps(converter(rows)))

输出是:

[
  
    "hotelId": 1,
    "rooms": [
      
        "roomId": 100,
        "prices": [
           "clientId": 1, "price":  "Default": 100.0  ,
           "clientId": 2, "price":  "Default": 98.0  
        ]
      ,
      
        "roomId": 101,
        "prices": [
           "clientId": 1, "price":  "Default": 200.0, "Discounted": 196.0  ,
           "clientId": 2, "price":  "Default": 202.0  ,
           "clientId": 3, "price":  "Default": 204.0  
        ]
      
    ]
  
]

附:注意c.ReduceFuncs.DictFirst 部分,这是每个忠诚度级别的第一个价格,您可能需要将其更改为DictLast / DictMax / DictMin / DictArray

【讨论】:

以上是关于将 Pandas Dataframe 转换为表记录的嵌套 JSON的主要内容,如果未能解决你的问题,请参考以下文章

将dict的dict转换为pandas DataFrame - 内存问题

将 Pandas tseries 对象转换为 DataFrame

将 pyspark groupedData 转换为 pandas DataFrame

Python Pandas:将 2,000,000 个 DataFrame 行转换为二进制矩阵 (pd.get_dummies()) 而不会出现内存错误?

如何将 sql 查询转换为 Pandas Dataframe 和 PySpark Dataframe

使用 pandas_udf 将 Spark Structured DataFrame 转换为 Pandas