如何通过PanderaPolars获取Schema校验无效行及相关技术问题
Pandera-Polars 常见问题解决方案
1. 获取Schema校验不通过的无效行(解决AttributeError无index问题)
Polars DataFrame本身没有index属性,无法直接复用Pandas版的索引关联逻辑。可以通过给原DataFrame添加自定义行标识的方式,关联校验失败的行:
import pandera.polars as pa import polars as pl # 定义基础Schema class MySchema(pa.SchemaModel): A: int = pa.Field(gt=0) B: str # 示例DataFrame df = pl.DataFrame({ "A": [1, -5, 200, 50], "B": ["normal", "normal", "box-quantity", "box-quantity"] }) # 步骤1:给DataFrame添加唯一行号 df_with_row_id = df.with_row_index("row_id") # 步骤2:用lazy模式执行校验,保留失败案例 validation_result = MySchema.validate(df_with_row_id, lazy=True) failure_cases = validation_result.failure_cases # 步骤3:通过行号关联得到无效行 invalid_rows = df_with_row_id.join( failure_cases, on="row_id", how="inner" ).drop(["row_id", "check", "schema_context", "column", "failure_case"]) print(invalid_rows)
执行后会输出所有校验不通过的行,比如A=-5和A=50(后者触发后续条件校验时会失败)。
2. 支持Lambda检查吗?
支持,但需要注意lambda参数是Polars Series对象,需遵循Polars的Series操作语法,不能直接用Pandas的逻辑:
class MySchema(pa.SchemaModel): A: int = pa.Field( check=lambda x: x > 0 # x是Polars Series,返回布尔Series ) B: str = pa.Field( check=lambda x: x.is_in(["normal", "box-quantity"]) )
如果需要基于整个DataFrame的跨列校验,lambda参数会接收整个DataFrame对象,同样要用Polars表达式操作:
class MySchema(pa.SchemaModel): A: int B: str = pa.Field( check=lambda df: pl.when(df["B"] == "box-quantity").then(df["A"] > 100).otherwise(True) )
3. 定义带过滤条件的校验(如B='box-quantity'时A>100)
可以通过pa.Check的when参数实现条件校验,或者直接在check逻辑中用Polars的when表达式:
方法1:使用Check.when参数
from pandera import Check class MySchema(pa.SchemaModel): A: int = pa.Field( checks=[ Check(lambda x: x > 0), # 全局校验A>0 # 条件校验:当B为box-quantity时,A必须>100 Check( lambda x: x > 100, when=lambda df: df["B"] == "box-quantity" ) ] ) B: str
方法2:用Polars表达式直接写逻辑
class MySchema(pa.SchemaModel): A: int = pa.Field( check=lambda df: pl.when(df["B"] == "box-quantity").then(df["A"] > 100).otherwise(True) ) B: str
两种方式都能实现基于列值的条件校验,推荐第一种,逻辑更清晰易维护。
内容的提问来源于stack exchange,提问作者Zodiark1991
相关产品推荐
相关产品推荐

