为何Pydantic模型无法插入Pandas DataFrame?有何解决办法?
Pydantic模型无法插入Pandas DataFrame的问题与解决方法
问题现象
将Pydantic模型实例插入Pandas DataFrame时会触发TypeError: object of type 'Test' has no len()错误,但dataclass或普通自定义类可正常插入。
正常工作的dataclass示例
import dataclasses import pandas as pd @dataclasses.dataclass class Test: name: str df = pd.DataFrame() inst = Test(name='Brian') df.at[0, 'test'] = inst print(df)
输出:
test 0 Test(name='Brian')
普通非dataclass类也可正常运行
报错的Pydantic示例
from pydantic import BaseModel import pandas as pd class Test(BaseModel): name: str df = pd.DataFrame() inst = Test(name='Brian') df.at[0, 'test'] = inst
执行后抛出错误:TypeError: object of type 'Test' has no len(),该问题存在于insert、loc、iloc、at、iat等DataFrame赋值方法中。
背景
工作中需要在DataFrame字段中插入和检索类对象,现需将部分原有类替换为Pydantic实现。
原因分析
Pandas通过is_list_like方法判断值是否为类列表可迭代类型,其中一个判断条件是检查对象的ndim属性是否大于0。Pydantic模型会被默认识别为ndim > 0,因此被判定为list_like类型;而dataclass或普通类无此属性,不会触发该判断逻辑。当Pandas将值视为list_like时,会尝试调用len()方法,但Pydantic模型未实现该方法,最终抛出错误。
解决方法
临时解决:添加ndim属性
在Pydantic类中显式设置ndim = 0,让Pandas不将其判定为list_like,从而正常插入:
from pydantic import BaseModel import pandas as pd class Test(BaseModel): name: str ndim = 0 # 添加该属性 df = pd.DataFrame() inst = Test(name='Brian') df.at[0, 'test'] = inst print(df)
输出:
test 0 name='Brian'
更优雅的替代方案(可选)
若不想修改Pydantic类定义,可在赋值时将实例包装为pd.Series,强制Pandas按单个值处理:
df.at[0, 'test'] = pd.Series([inst])[0]
内容的提问来源于stack exchange,提问作者b_swid
相关产品推荐
相关产品推荐

