将 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()) 而不会出现内存错误?