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)
问题根源
- Schema结构错误:给数组类型(
"type": "array")使用了properties关键字,但properties是针对对象类型(object)的规则,数组类型需要用items来定义每个元素的结构。当前Schema相当于没有给数组元素设置任何验证规则,自然不会触发错误。 - 浮点数精度隐患:即便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é
相关产品推荐
相关产品推荐

