如何将 Pydantic BaseModels 列表转换为 Pandas Dataframe
Posted
技术标签:
【中文标题】如何将 Pydantic BaseModels 列表转换为 Pandas Dataframe【英文标题】:How to convert a list of Pydantic BaseModels to Pandas Dataframe 【发布时间】:2020-09-01 00:32:12 【问题描述】:我似乎找不到任何将 Pydantic BaseModels 列表简单地转换为 Pandas Dataframe 的内置方法。
from pydantic import BaseModel
import pandas as pd
class SomeModel(BaseModel):
col1: str
col2: str
data = [SomeModel(**'col1': 'foo', 'col2': 'bar')] * 10
pd.DataFrame(data)
输出
>> 0 1
>> 0 (col1, foo) (col2, bar)
>> 1 (col1, foo) (col2, bar)
>> ...
以这种方式将列作为数据加载。一种解决方法是执行以下操作
pd.Dataframe([model.dict() for model in data])
输出
>> col1 col2
>> 0 foo bar
>> 1 foo bar
>> ...
但是,对于大量数据,这种方法有点慢。有更快的方法吗?
【问题讨论】:
【参考方案1】:不确定它是否更快,但FastAPI 公开了jsonable_encoder
,它基本上对BaseModel
的任意嵌套结构执行相同的转换:
from fastapi.encoders import jsonable_encoder
pd.DataFrame(jsonable_encoder(data))
【讨论】:
【参考方案2】:快速而肮脏的分析会产生以下值:
from pydantic import BaseModel
import pandas as pd
from fastapi.encoders import jsonable_encoder
class SomeModel(BaseModel):
col1: int
col2: str
data = [SomeModel(col1=1,col2="foo"),SomeModel(col1=2,col2="bar")]*4*10**5
import cProfile
cProfile.run( 'pd.DataFrame([s.dict() for s in data])' ) # around 8.2s
cProfile.run( 'pd.DataFrame(jsonable_encoder(data))' ) # around 30.8s
cProfile.run( 'pd.DataFrame([s.__dict__ for s in data])' ) # around 1.7s
cProfile.run( 'pd.DataFrame([dict(s) for s in data])' ) # around 3s
【讨论】:
以上是关于如何将 Pydantic BaseModels 列表转换为 Pandas Dataframe的主要内容,如果未能解决你的问题,请参考以下文章
如何以灵活的方式将嵌套的 pydantic 模型用于 sqlalchemy
您将如何使用带有 FastAPI 的 asyncpg 将选择查询的返回值映射到 pydantic 模型以进行输出和验证?