news 2026/2/24 7:55:29

如何轻松使用 Pandera 验证数据

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
如何轻松使用 Pandera 验证数据

原文:towardsdatascience.com/how-to-easily-validate-your-data-with-pandera-a9cd22c515a5?source=collection_archive---------7-----------------------#2024-08-14

学习如何构建一个简单的数据模型,通过类型提示来验证数据

https://medium.com/@conalhenderson?source=post_page---byline--a9cd22c515a5--------------------------------https://towardsdatascience.com/?source=post_page---byline--a9cd22c515a5-------------------------------- Conal Henderson

·发布于Towards Data Science ·阅读时间:6 分钟·2024 年 8 月 14 日

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9cb51cb89dabc5e3cfd2ce6056273fff.png

图片来自Christina Morillo在Pixels

许多网上的pandas教程教授如何操作和清理数据,但很少有教程展示如何验证数据是否正确。这就是使用pandera进行数据验证的意义所在。

为什么需要数据验证?

就像任何人一样,当我第一次查看数据时,我会进行基本的调查,比如查看数据类型、检查空值,并可视化数据分布,来大致判断如何处理数据。

然而,我们需要数据验证来确保数据遵循业务逻辑。例如,对于包含产品信息的数据,我们需要验证产品价格没有负值;或者当用户提供电子邮件地址时,我们需要验证该电子邮件地址符合已知的模式。

忽视数据验证会对分析和建模产生下游影响,因为数据质量差会导致偏差、噪声和不准确性增加

最近一个数据验证不当的例子是Zillow 的房价算法,其高估了 Zillow 所购买的 2/3 的房产,导致 2021 年第三季度和第四季度 Zillow 房产估值下降了 5 亿美元。

这表明,你不仅需要关注数据是否符合验证标准,还需要关注数据是否反映了现实情况,而在 Zillow 的案例中,数据并未做到这一点。

什么是 Pandera?

[Pandera](https://pandera.readthedocs.io/en/stable/index.html)是一个 Python 包,提供了一个文档齐全且灵活的 API,能够与pandaspolars这两个主要的 Python 数据库进行集成。

我们可以使用pandera通过业务逻辑和领域知识来验证数据框架的数据类型和属性。

大纲

本文将覆盖以下内容:

设置

安装依赖

pip install pandas pip install pandera

数据

本文使用的数据是通过 Claude.ai 生成的假足球市场数据。

定义验证模型

该包允许你定义验证模式或数据验证模型,后者与另一个很棒的数据验证包[Pydantic](https://docs.pydantic.dev/latest/)非常相似。

对于本次练习,我们将专注于验证模型,因为它允许与我们的 Python 代码集成类型提示,并且我发现它比验证模式稍微更易于阅读。然而,如果你想利用验证模式,模型也有方法将其转换为模式。

你可以在这里找到关于两种验证方法的信息:

加载数据

data={'dob':pd.to_datetime(['1990-05-15','1988-11-22','1995-03-10','1993-07-30','1992-01-18','1994-09-05','1991-12-03','1989-06-20','1996-02-14','1987-08-08']),'age':[34,35,29,31,32,30,32,35,28,37],'country':['England','Spain','Germany','France','Italy','Brazil','Argentina','Netherlands','Portugal','England'],'current_club':['Manchester United','Chelsea','Bayern Munich','Paris Saint-Germain','Juventus','Liverpool','Barcelona','Ajax','Benfica','Real Madrid'],'height':pd.array([185,178,None,176,188,182,170,None,179,300],dtype='Int16'),'name':['John Smith','Carlos Rodriguez','Hans Mueller','Pierre Dubois','Marco Rossi','Felipe Santos','Diego Fernandez','Jan de Jong','Rui Silva','Gavin Harris'],'position':['Forward','Midfielder','Defender','Goalkeeper','Defender','Forward','Midfielder','Defender','Forward','Midfielder'],'value_euro_m':[75.5,90.2,55.8,40.0,62.3,88.7,70.1,35.5,45.9,95.0],'joined_date':pd.to_datetime(['2018-07-01','2015-08-15',None,'2017-06-30','2016-09-01',None,'2021-07-15','2014-08-01','2022-01-05','2019-06-01']),'number':[9,10,4,1,3,11,8,5,7,17],'signed_from':['Everton','Atletico Madrid','Borussia Dortmund',None,'AC Milan','Santos',None,'PSV Eindhoven','Sporting CP','Newcastle United'],'signing_fee_euro_m':[65.0,80.5,45.0,None,55.0,75.2,60.8,None,40.5,85.0],'foot':['right','left','right','both','right','left','left','right','both','right'],}df=pd.DataFrame(data)

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e3e1bc6302c113c4e0752e131a944a58.png

图片来自作者

检查数据类型

data.types

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/6e878c39c8dda42332ac60e5846fe134.png

图片来自作者

我们可以使用数据类型来帮助定义我们的数据模型。

创建数据模型

classPlayerSchema(pa.DataFrameModel):dob:Series[pd.Timestamp]=pa.Field(nullable=False,ge=pd.Timestamp('1975-01-01'))age:Series[pa.Int64]=pa.Field(ge=0,le=50,nullable=False)country:Series[pa.String]=pa.Field(nullable=False)current_club:Series[pa.String]=pa.Field(nullable=False)height:Series[pa.Int16]=pa.Field(ge=120,le=210,nullable=True)name:Series[pa.String]=pa.Field(nullable=False)position:Series[pa.String]=pa.Field(nullable=False)value_euro_m:Series[pa.Float64]=pa.Field(ge=0,le=200)joined_date:Series[pd.Timestamp]=pa.Field(nullable=True,ge=pd.Timestamp('2000-01-01'))number:Series[pa.Int64]=pa.Field(ge=0,le=99)signed_from:Series[pa.String]=pa.Field(nullable=True)signing_fee_euro_m:Series[pa.Float64]=pa.Field(ge=0,le=300,nullable=True)foot:Series[pa.String]=pa.Field(nullable=False,isin=['right','left','both','unknown'])

上面,我们通过子类化pa.DataFrameModel定义了一个模式,这与在[Pydantic](https://docs.pydantic.dev/latest/)中子类化BaseModel的方式相同。然后,我们用相应的数据集中的列填充了该模式,提供了每列的预期数据类型,并使用pa.Field方法定义了边界

Panderapandas的集成非常好,意味着你可以使用pandas数据类型(例如pd.Timestamp)以及 pandera 数据类型(例如pa.Int64)来定义每一列。

重用字段

为了避免重复字段,我们可以通过使用内建的 Python 库functools中的partial来重用字段。

fromfunctoolsimportpartial NullableField=partial(pa.Field,nullable=True)NotNullableField=partial(pa.Field,nullable=False)

partial类创建了一个应用原始函数指定子集参数的新函数

上面,我们为模型变量创建了两个可重用字段,这些变量要么包含空值,要么不包含空值。

我们更新后的数据模型如下所示

classPlayerSchema(pa.DataFrameModel):dob:Series[pd.Timestamp]=pa.Field(nullable=False,ge=pd.Timestamp('1975-01-01'))age:Series[pa.Int64]=pa.Field(ge=0,le=50,nullable=False)country:Series[pa.String]=NotNullableField()current_club:Series[pa.String]=NotNullableField()height:Series[pa.Int16]=pa.Field(ge=120,le=250,nullable=True)name:Series[pa.String]=NotNullableField()position:Series[pa.String]=NotNullableField()value_euro_m:Series[pa.Float64]=pa.Field(ge=0,le=200)joined_date:Series[pd.Timestamp]=pa.Field(nullable=True,ge=pd.Timestamp('2000-01-01'))number:Series[pa.Int64]=pa.Field(ge=0,le=99)signed_from:Series[pa.String]=NullableField()signing_fee_euro_m:Series[pa.Float64]=pa.Field(ge=0,le=300,nullable=True)foot:Series[pa.String]=pa.Field(nullable=False,isin=['right','left','both','unknown'])

由于partial创建了一个新函数,我们必须使用括号来调用我们的新字段。

验证数据

现在数据模型已经定义好,我们可以用它来验证数据。

@pa.check_typesdefload_data()->DataFrame[PlayerSchema]:returnpd.read_parquet('../data/player_info_cleaned.parquet')

为了验证数据,我们使用类型提示和装饰器的结合@pa.check_types装饰器表示数据应该按照返回类型提示DataFrame[PlayerSchema]中定义的模式进行验证。

@pa.check_typesdefvalidate_data(df:DataFrame)->DataFrame[PlayerSchema]:try:returndfexceptpa.errors.SchemaErrorase:print(e)validate_data(df)# error in check_types decorator of function 'load_data': Column 'height' failed element-wise validator number 1: less_than_or_equal_to(210) failure cases: 300

通过使用 try-except 块,我们可以捕获加载和验证数据时抛出的任何错误。结果显示,‘height’列未通过小于或等于测试,其中一个标记为 300cm 的身高是不正确的。

清理数据

清理数据有很多策略,其中一些我在之前的文章中已详细介绍。

[## 精通 Pandas 构建模块化和可重用的数据管道

通过利用 pandas 实现关键的数据处理策略,构建模块化、可重用且高效的数据管道。

medium.com](https://medium.com/@conalhenderson/master-pandas-to-build-modular-and-reusable-data-pipelines-1d12b003a423?source=post_page-----a9cd22c515a5--------------------------------)

为了简化处理,我将使用人口的中位数身高来填补所有大于 210cm 的值。

defclean_height(df:DataFrame)->DataFrame[PlayerSchema]:data=df.copy()data.loc[data[PlayerSchema.height]>210,PlayerSchema.height]=round(data[PlayerSchema.height].median())returndata df=clean_height(df)

pandera的另一个有用特性是,架构可以用来指定你想要分析的列名,例如,我们可以使用PlayerSchema.height提高代码的可读性并鼓励一致性,而不是显式地标记‘height’。

重新验证

由于我们的数据已经被加载进来,我们可以调整之前的函数,使其接受数据框作为输入,运行数据框并通过 try-except 块进行评估,并使用装饰器和类型提示。

validate_data_2(df)# if there are no errors, the dataframe is the output.

这次没有错误,意味着数据框被作为函数的输出返回。

结论

这篇文章概述了为什么验证数据非常重要,以确保数据与业务逻辑一致并反映现实世界,以 Zillow 为例,说明了缺乏数据验证可能带来的严重后果。

使用了Pandera来展示如何轻松地将数据验证与pandas集成,以快速验证一个架构,该架构与Pydantic非常相似,使用了装饰器类型提示。还展示了如何使用pa.Field设置数据的边界,并且当与partial一起使用时,可以创建可重用字段,从而提高代码的可读性。

希望你觉得这篇文章有用,感谢阅读。如果有任何问题,可以通过LinkedIn与我联系!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/22 16:58:16

深度拆解 `std::unordered_map` 的‘渐进式再哈希’:如何避免在插入海量数据时产生的瞬时卡顿?

各位技术同仁,大家好。今天我们将深入探讨一个在高性能计算和系统编程中至关重要的话题:哈希表的动态扩容机制,特别是如何避免在海量数据插入时可能出现的瞬时卡顿。我们将聚焦于C标准库中的std::unordered_map,并着重拆解一个高级…

作者头像 李华
网站建设 2026/2/17 0:54:14

一款可以阻止网络钓鱼诈骗的解决方案?收藏这篇就够了

“你继承了一笔财富。要转账,我需要你的银行账户凭证。” 你是否也遇见过此类的电话诈骗话术。 根据2022年数据泄露调查报告,25%的数据泄露涉及网络钓鱼。 这是怎么发生的?参与网络钓鱼的欺诈者一般都是心理方面的高手。他们知道如何营造紧…

作者头像 李华
网站建设 2026/2/22 20:51:44

从 Web 安全到二进制:转行网络安全的进阶方向选择

从 Web 安全到二进制:转行网络安全的进阶方向选择 引言 转行网络安全一段时间后,很多同学会陷入 “方向迷茫”—— 一直做 Web 安全,感觉技术瓶颈明显,想进阶却不知道选什么方向;看到别人做二进制安全、工控安全&…

作者头像 李华
网站建设 2026/2/23 14:24:09

论文AI率过高怎么办?大学生必看的降AI率指南(超简单)

一、为什么我查重过了,AI率却超标?【认知盲区】 你是不是也遇到过这种情况:论文查重率明明控制在10%以内,导师却指着检测报告问:"这AI生成痕迹太明显了吧?" 很多同学都忽略了:查重≠…

作者头像 李华
网站建设 2026/2/20 14:09:27

No.940 ‘基于S7-200 PLC和组态王的车辆出入库管理系统停车场控制系统

No.940 基于S7-200 PLC和组态王的车辆出入库管理系统停车场控制系统 刚接手停车场改造项目那会儿,甲方甩过来个奇葩需求:要在老仓库区搞智能车辆管理系统,还得用西门子S7-200 PLC配组态王。这组合搁现在看着有点复古,但胜在稳定耐…

作者头像 李华