如何通过pydantic过滤掉NaN

问题描述 投票:0回答:4

如何在 pytdantic 浮点验证中过滤掉 NaN?

from pydantic import BaseModel

class MySchema(BaseModel):
    float_value: float
python nan pydantic
4个回答
3
投票

您可以使用

confloat
并将上限设置为无穷大或将下限设置为负无穷大。由于所有与 NaN 的数字比较都返回 False,这将使 pydantic 拒绝 NaN,同时保持所有其他行为相同(包括解析、从 int 到 float 的转换,...)。

from pydantic import BaseModel, confloat

class MySchema(BaseModel):
    float_value: confloat(ge=-float('inf'))
    # or:
    # float_value: confloat(le=float('inf'))

注意:您还可以使用

gt
lt
confloat
参数而不是
ge
le
来排除无穷大值。

测试:

m = MySchema(float_value=float('nan'))

输出:

pydantic.error_wrappers.ValidationError: 1 validation error for MySchema
float_value
  ensure this value is greater than or equal to -inf (type=value_error.number.not_ge; limit_value=-inf)

1
投票

pydantic 版本 >= 1.10 的最新答案是使用

confloat
并相应地设置其
allow_inf_nan

class Finite(BaseModel):
    value: confloat(allow_inf_nan=False)

这样,参数

float("inf")
-float("inf")
float("nan")
-float("inf")
将产生
ValidationError

请参阅 confloat

文档。


1
投票
import maths
from pydantic import BaseModel, validator

class MySchema(BaseModel):
    float_value: float

    @validator('*', pre=True)
    def split_str(cls, v):
        if isinstance(v, float):
            if maths.isnan(v):
                raise ValueError("value can't be Not-a-Number (NaN)")
            return v
        return v   

0
投票

定义验证的自定义类型,在 pydantic 中有详细记录:

class NoNanFloat(float):
    
    @classmethod
    def __get_validators__(cls):
        yield cls.validate
        
    @classmethod
    def __modify_schema__(cls, field_schema):
        # you can ommit this method
        field_schema.update(
            examples=['24.2,15.2'],
        )

    @classmethod
    def validate(cls, v):
        if not isinstance(v, float):
            raise TypeError('float required')
        if v!=v: # you can use here also maths.isnan(v):
            raise ValueError("value can't be Not-a-Number (NaN)")
        return cls(v)

    def __repr__(self):
        # you can also ommit this method, but it looks good when printing. 
        return f'NoNanFloat({super().__repr__()})'
    
class MySchema(BaseModel):
    no_nan_float_value: NoNanFloat
    other_float_value: float
    other: Any

这种方法有很多优点,因为它允许您根据需要拥有两种类型的“浮动”,因此您可以有一些允许 nan 和其他不允许的。

我还允许您使用接受 nan 的“任何”类型,以及按预期行为的类型联合。

© www.soinside.com 2019 - 2024. All rights reserved.