【问题标题】:How to convert a list of Pydantic BaseModels to Pandas Dataframe如何将 Pydantic BaseModels 列表转换为 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
>> ...

但是,对于大量数据,这种方法有点慢。有更快的方法吗?

【问题讨论】:

    标签: python pandas pydantic


    【解决方案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
      

      【讨论】:

        猜你喜欢
        • 2022-01-23
        • 2013-02-13
        • 2021-11-10
        • 2021-03-01
        • 2019-11-28
        • 1970-01-01
        • 2014-01-05
        • 2021-11-28
        相关资源
        最近更新 更多