我是Pydantic和Pandera的新手,需要一些关于类实例化和初始化的帮助。
我在一个文件sim.py
:中有以下代码
import pandera as pa
from pydantic import BaseModel
from datetime import datetime
class ScheduleDF(pa.SchemaModel):
person_id: Series[int] = pa.Field(ge=0, coerce=True)
shift_id: Series[int] = pa.Field(ge=0, coerce=True)
start_time: Series[datetime]
end_time: Series[datetime]
class Schedule(BaseModel):
schedule_df: DataFrame[ScheduleDF]
events_df: DataFrame[EventsDF]
@pa.check_types
def initialize_from_df(self, schedule_df: DataFrame[ScheduleDF]):
self.schedule_df = schedule_df
以及另一个文件sim_test.py
:中的以下代码
from sim import ScheduleDF, Schedule
def test_schedule():
y = 2022
m = 9
d = 1
schedule_df = DataFrame[ScheduleDF](
{'person_id': [1, 2], 'shift_id': [10, 20],
'start_time': [datetime(y, m, d, 0, 0, 1), datetime(y, m, d, 0, 0, 5)],
'end_time': [datetime(y, m, d, 0, 0, 3), datetime(y, m, d, 0, 0, 6)]
}
)
sample_schedule = Schedule()
sample_schedule.initialize_from_df(schedule_df)
test_schedule()
当我运行sim_testing.py
时,我得到以下错误:
pydantic.error_wrappers.ValidationError: 2 validation errors for Schedule
schedule_df
field required (type=value_error.missing)
events_df
field required (type=value_error.missing)
我明白为什么events_df
丢失了——我没有在test_schedule()
内部初始化它。但是,我似乎已经初始化了schedule_df
。
我尝试在initialize_from_df()
的@pa.check_types
装饰器之上添加@classmethod
,并按照这里和这里的建议将该函数中的self
更改为cls
,但它仍然给了我同样的错误。这似乎是一个Pydantic的问题,而不是Pandera的问题。
如果能帮我弄清楚发生了什么以及如何纠正,我将不胜感激。谢谢!
在Schedule
类中,您定义了两个必填字段schedule_df
和event_df
。
class Schedule(BaseModel):
schedule_df: DataFrame[ScheduleDF]
events_df: DataFrame[EventsDF]
因此,当您尝试用sample_schedule = Schedule()
实例化它时,它必然会失败,因为您没有为这两个必填字段提供任何值。
基本上,你有两条前进的道路:
- 在实例化时传递
ScheduleDF
和EventsDF
的实例,就像这样(注意:您忘记给我们EventsDF
类的定义,所以我只是编一个(:
schedule_df = DataFrame[ScheduleDF](
{
'person_id': [1, 2],
'shift_id': [10, 20],
'start_time': [datetime(y, m, d, 0, 0, 1), datetime(y, m, d, 0, 0, 5)],
'end_time': [datetime(y, m, d, 0, 0, 3), datetime(y, m, d, 0, 0, 6)]
}
)
events_df = DataFrame[EventsDF](
{
'event_id': [1],
'start_time': [datetime(y, m, d, 0, 0, 3)],
'end_time': [datetime(y, m, d, 0, 0, 4)]
}
)
sample_schedule = Schedule(schedule_df=schedule_df, events_df=events_df)
- 或者,如果之后确实要为
schedule_df
和events_df
赋值,请在类定义中将它们设为可选值:
from typing import Optional
class Schedule(BaseModel):
schedule_df: Optional[DataFrame[ScheduleDF]]
events_df: Optional[DataFrame[EventsDF]]
这样,调用sample_schedule = Schedule()
将起作用,而sample_schedule
基本上将包含schedule_df=None events_df=None
。