关于Pandera未报告NaN失败案例及验证异常的技术问询
Pandera DataFrame级验证中NaN值不被报告为失败案例的原因分析
问题现象复现
示例1:含NaN的DataFrame验证,仅非NaN值被报告为失败
import numpy as np import pandas as pd import pandera as pa dataframe = pd.DataFrame({'column_A': ['ABC company', 'BBB company', 'ABC company', 'CCC company'], 'column_B': ['1000', np.NaN, '2000', np.NaN] }) # 定义DataFrame级校验规则 check_AB = pa.Check( lambda df: (df['column_A'].str.contains('ABC')) & (~df['column_B'].isna()), name='check_AB' ) schema = pa.DataFrameSchema( columns={ 'column_A': pa.Column(pa.String), 'column_B': pa.Column(pa.String, nullable=True) }, checks=check_AB # 应用DataFrame级校验 ) schema.validate(dataframe, lazy=True)
执行后,NaN值未出现在失败案例中,仅非NaN的不符合规则行被报告。
示例2:调整数据后,依然仅非NaN值被列为失败案例
dataframe = pd.DataFrame({'column_A': ['ABC company', np.nan, 'ABC company', np.nan], 'column_B': [1000, np.NaN, 2000, 4] }) # 定义DataFrame级校验规则 check_AB = pa.Check( lambda df: (df['column_A'].str.contains('ABC')) & (df['column_B'] >= 7), name='check_AB' )
验证结果仍只展示非NaN的失败行,涉及NaN的行未被纳入失败报告。
示例3:通过错误对象观察到同样现象
try: schema.validate(dataframe, lazy=True) except pa.errors.SchemaErrors as e: e2 = e; print(e2.failure_cases)
输出的失败案例列表中依然没有包含NaN的行。
示例4:所有失败案例均为NaN时,未触发验证错误
dataframe = pd.DataFrame({'column_A': ['ABC company', np.nan, 'ABC company', np.nan], 'column_B': [1000, np.NaN, 2000, np.nan] }) # 定义DataFrame级校验规则 check_AB = pa.Check( lambda df: (df['column_A'].str.contains('ABC')) & (df['column_B'] >= 7), name='check_AB' ) schema = pa.DataFrameSchema( columns={ 'column_A': pa.Column(pa.String, nullable=True), 'column_B': pa.Column(pa.Float, nullable=True) }, checks=check_AB # 应用DataFrame级校验 )
此时Pandera未抛出任何验证错误,直接判定数据符合规则。
原因解析
1. Pandera对NaN值的默认处理逻辑
Pandera的Check组件默认会自动忽略NaN值:在Pandas中,涉及NaN的布尔运算结果会返回NaN,而Pandera仅将校验结果为明确False的行判定为失败案例,NaN会被直接排除在失败统计之外,因此不会出现在报告中。
比如在你的校验逻辑里:
- 当
column_A或column_B为NaN时,df['column_A'].str.contains('ABC')或df['column_B'] >=7的运算结果是NaN - Pandera不会将这类NaN结果视为失败,自然不会把对应行纳入失败案例。
2. 全NaN结果时不触发错误的原因
当所有行的校验结果都是NaN时,Pandera认为没有“明确的失败案例”,因此不会抛出SchemaErrors异常。因为校验逻辑没有产生任何False结果,Pandera会判定数据符合校验要求,即使实际逻辑上NaN行并不满足规则。
解决方案
如果需要将NaN值纳入失败案例统计,只需在定义Check时显式设置ignore_na=False参数,关闭默认的NaN忽略逻辑:
check_AB = pa.Check( lambda df: (df['column_A'].str.contains('ABC')) & (df['column_B'] >= 7), name='check_AB', ignore_na=False # 强制将NaN结果视为失败 )
此时,所有校验结果为NaN的行都会被视为失败案例纳入报告;当所有行的校验结果都是NaN时,也会正常触发验证错误。
内容的提问来源于stack exchange,提问作者silence_of_the_lambdas
相关产品推荐
相关产品推荐

