You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame中JSON Schema验证三位小数失效的修复方法

问题:JSON Schema的multipleOf未正确验证小数位数

我尝试用JSON Schema的"multipleOf": 0.001规则验证scores字段必须保留三位小数,但当记录中出现五位小数的"scores": [1.12345]时,验证未报错反而返回通过,输出如下:

Validation ok
     scores
0 1.12345

相关代码:

import jsonschema
import pandas as pd

schema = {
    "type": "array",
    "properties": {"scores": {"type": "number", "multipleOf": 0.001}},
}


df = pd.DataFrame(
    {
        "scores": [1.12345],
    }
)

validator = jsonschema.Draft202012Validator(schema)

try:
    validator.validate(instance=df.to_dict("records"))
    print("Validation ok")

except jsonschema.ValidationError as e:
    print(f"Validation error: {e.message}")

print(df)

问题根源

  1. Schema结构错误:给数组类型("type": "array")使用了properties关键字,但properties是针对对象类型(object)的规则,数组类型需要用items来定义每个元素的结构。当前Schema相当于没有给数组元素设置任何验证规则,自然不会触发错误。
  2. 浮点数精度隐患:即便Schema结构正确,直接用multipleOf: 0.001验证浮点数也可能因为二进制浮点数的精度问题出现误判(比如1.123在内存中可能是接近但不完全等于1.123的二进制值)。

修复方案

1. 修正Schema结构(核心修复)

把数组元素的验证规则放到items里,明确数组中的每个元素是包含scores字段的对象:

schema = {
    "type": "array",
    "items": {  # 替换properties为items,定义数组元素的结构
        "type": "object",
        "properties": {
            "scores": {"type": "number", "multipleOf": 0.001}
        },
        "required": ["scores"]  # 可选:强制要求scores字段必须存在
    }
}

2. 解决浮点数精度问题(可选但推荐)

如果担心浮点数精度导致的验证偏差,可以用以下两种方式规避:

方案A:转整数验证

把数值乘以1000转为整数,验证是否为整数(即原数值是三位小数):

import jsonschema
import pandas as pd

# 先处理数据:转成三位小数对应的整数
df["scores_int"] = (df["scores"] * 1000).round().astype(int)

# 验证整数字段
schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "scores_int": {"type": "integer"}
        }
    }
}

validator = jsonschema.Draft202012Validator(schema)
try:
    validator.validate(instance=df.to_dict("records"))
    # 额外检查原数值和四舍五入后的值是否一致
    if (df["scores"].round(3) == df["scores"]).all():
        print("Validation ok")
    else:
        print("Validation error: scores字段必须保留三位小数")
except jsonschema.ValidationError as e:
    print(f"Validation error: {e.message}")

方案B:直接对比四舍五入后的值

跳过JSON Schema,直接用Pandas检查每个值是否和三位小数四舍五入后的结果相等:

import pandas as pd

df = pd.DataFrame({"scores": [1.12345]})

# 检查所有scores是否符合三位小数要求
if not (df["scores"].round(3) == df["scores"]).all():
    print("Validation error: scores字段必须保留三位小数")
else:
    print("Validation ok")

最终完整修复代码(修正Schema版本)

import jsonschema
import pandas as pd

# 修正后的Schema
schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "scores": {"type": "number", "multipleOf": 0.001}
        },
        "required": ["scores"]
    }
}


df = pd.DataFrame({"scores": [1.12345]})

validator = jsonschema.Draft202012Validator(schema)

try:
    validator.validate(instance=df.to_dict("records"))
    print("Validation ok")
except jsonschema.ValidationError as e:
    print(f"Validation error: {e.message}")

print(df)

运行这段代码后,会正确输出验证错误:

Validation error: 1.12345 is not a multiple of 0.001
     scores
0 1.12345

内容的提问来源于stack exchange,提问作者Antonio José

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:55:59