用 Pandera 高效验证和清洗 Pandas 数据集——实用分步指南

article/2025/6/8 12:30:35

当我们处理数据时,确保数据不脏、不无效非常重要——比如检查空值、缺失值,或某列类型不允许的数字。这些检查至关重要,因为劣质数据会导致错误分析、模型失败,并浪费大量时间和资源。

你可能已经用传统的 Pandas 方法清理和验证过数据,但在本教程中,我想向你介绍一款更强大的 Python 库:Pandera。Pandera 提供了灵活且表达力强的 API,可对类 DataFrame 对象进行数据验证。与手动检查相比,它更快、更具扩展性。你只需创建定义数据结构、数据类型和规则的 schema(模式),然后 Pandera 会根据这些 schema 检查你的数据,指出不符合要求的地方,让你能在早期发现并修正问题,避免日后遇到大麻烦。

Clean and Validate Your Data Using Pandera

本指南假设你已经具备一定的 Python 和 Pandas 基础。让我们一步步学习如何在工作流中使用 Pandera。


第 1 步:环境配置

首先,需要安装必要的包:

pip install pandera pandas

安装完成后,导入所需库,并验证安装结果:

import pandas as pd
import pandera as paprint("pandas version:", pd.__version__)
print("pandera version:", pa.__version__)

输出应如下,显示 pandas 和 Pandera 的版本,确认安装成功:

pandas version: 2.2.2
pandera version: 0.0.0+dev0

第 2 步:创建示例数据集

让我们创建一个包含有意错误的客户信息数据集,便于演示清洗和验证流程:

import pandas as pd# 包含错误的客户数据集
data = pd.DataFrame({"customer_id": [1, 2, 3, 4, "invalid"],  # "invalid" 不是整数"name": ["Maryam", "Jane", "", "Alice", "Bobby"],  # 包含空名字"age": [25, -5, 30, 45, 35],  # 年龄为负数无效"email": ["mrym@gmail.com", "jane.s@yahoo.com", "invalid_email", "alice@google.com", None]  # 邮箱无效或缺失
})print("原始 DataFrame:")
print(data)

输出:

原始 DataFrame:customer_id    name  age             email
0           1  Maryam   25    mrym@gmail.com
1           2    Jane   -5  jane.s@yahoo.com
2           3           30     invalid_email
3           4   Alice   45  alice@google.com
4     invalid   Bobby   35              None

数据集中的问题:

  • customer_id

    :包含字符串 "invalid",应为整数

  • name

    :存在空字符串

  • age

    :包含负数(-5)

  • email

    :格式无效(invalid_email)和缺失值(None)


第 3 步:定义 Pandera Schema

Pandera 的 schema 定义了 DataFrame 期望的结构和约束。我们将用 DataFrameSchema 为每一列指定规则:

import pandera as pa
from pandera import Column, Check, DataFrameSchema# 定义 schema
schema = DataFrameSchema({"customer_id": Column(dtype="int64",checks=[Check.isin(range(1, 1000)),  # ID 在 1~999 之间Check(lambda x: x > 0, element_wise=True)  # 必须为正数],nullable=False),"name": Column(dtype="string",checks=[Check.str_length(min_value=1),Check(lambda x: x.strip() != "", element_wise=True)],nullable=False),"age": Column(dtype="int64",checks=[Check.greater_than(0),  # 必须为正Check.less_than_or_equal_to(120)  # 合理范围],nullable=False),"email": Column(dtype="string",checks=[Check.str_matches(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")],nullable=False)
})

第 4 步:初始验证

现在,用 schema 验证 DataFrame。Pandera 的 validate 方法会检查数据是否符合 schema,设置 lazy=True 可收集所有错误:

print("\n初始验证:")
try:validated_df = schema.validate(data, lazy=True)print("数据有效!")print(validated_df)
except pa.errors.SchemaErrors as e:print("验证失败,具体问题如下:")print(e.failure_cases[['column', 'check', 'failure_case', 'index']])

验证会失败,错误信息类似:

验证失败,具体问题如下:column                check         failure_case index
0  customer_id   isin(range(1, 1000))            invalid     4
1         name      str_length(1, None)                        2
2         name                                    2
3          age           greater_than(0)                -5     1
4        email              not_nullable              None     4
5        email  str_matches('...')      invalid_email     2
6  customer_id             dtype('int64')           object  None
...

第 5 步:清洗数据

我们已发现问题,接下来逐步清洗数据:

  • customer_id

    :移除非整数或无效 ID

  • name

    :移除空字符串

  • age

    :移除负数或不合理年龄

  • email

    :移除无效或缺失邮箱

# 5a. 清洗 customer_id
data["customer_id"] = pd.to_numeric(data["customer_id"], errors="coerce")
data = data[data["customer_id"].notna()]
data = data[data["customer_id"].isin(range(1, 1000))]
data["customer_id"] = data["customer_id"].astype("int64")# 5b. 清洗 name
data = data[data["name"].str.strip() != ""]
data["name"] = data["name"].astype("string[python]")# 5c. 清洗 age
data = data[data["age"] > 0]
data = data[data["age"] <= 120]# 5d. 清洗 email
data = data[data["email"].notna()]
data = data[data["email"].str.match(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")]
data["email"] = data["email"].astype("string[python]")print("清洗后的 DataFrame:")
print(data)

清洗后 DataFrame:

清洗后的 DataFrame:customer_id    name  age             email
0            1  Maryam   25    mrym@gmail.com
3            4   Alice   45  alice@google.com

第 6 步:再次验证数据

验证清洗后的 DataFrame,确保其符合 schema:

print("\n最终验证:")
try:validated_df = schema.validate(data, lazy=True)print("清洗后的数据有效!")print(validated_df)
except pa.errors.SchemaErrors as e:print("清洗后验证失败,错误如下:")print(e.failure_cases[['column', 'check', 'failure_case', 'index']])

输出:

最终验证:
清洗后的数据有效!customer_id    name  age             email
0            1  Maryam   25    mrym@gmail.com
3            4   Alice   45  alice@google.com

第 7 步:构建可复用的数据处理管道

可以将清洗和验证流程封装为可复用的函数:

def process_data(df, schema):"""用 Pandera schema 处理并验证 DataFrame。参数:df: 输入的 pandas DataFrameschema: Pandera DataFrameSchema返回:验证且清洗后的 DataFrame,若验证失败则返回 None"""data_clean = df.copy()data_clean["customer_id"] = pd.to_numeric(data_clean["customer_id"], errors="coerce")data_clean = data_clean[data_clean["customer_id"].notna()]data_clean = data_clean[data_clean["customer_id"].isin(range(1, 1000))]data_clean["customer_id"] = data_clean["customer_id"].astype("int64")data_clean = data_clean[data_clean["name"].str.strip() != ""]data_clean["name"] = data_clean["name"].astype("string")data_clean = data_clean[data_clean["age"] > 0]data_clean = data_clean[data_clean["age"] <= 120]data_clean["age"] = data_clean["age"].astype("int64")data_clean = data_clean[data_clean["email"].notna()]data_clean = data_clean[data_clean["email"].str.match(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")]data_clean["email"] = data_clean["email"].astype("string")data_clean = data_clean.reset_index(drop=True)try:validated_df = schema.validate(data_clean, lazy=True)print("数据处理成功!")return validated_dfexcept pa.errors.SchemaErrors as e:print("清洗后验证失败,错误如下:")print(e.failure_cases[['column', 'check', 'failure_case', 'index']])return None# 测试管道
print("\n测试管道:")
final_df = process_data(data, schema)
print("最终处理后的 DataFrame:")
print(final_df)

输出:

测试管道:
数据处理成功!
最终处理后的 DataFrame:customer_id    name  age             email
0            1  Maryam   25    mrym@gmail.com
1            4   Alice   45  alice@google.com

结论

Pandera 是保障 pandas 数据工作流数据质量的强大工具。通过定义 schema,你能及早发现错误,强制执行数据一致性,并自动化数据清洗。本文你学到了:

  • 安装 Pandera 并设置样例数据集

  • 定义包含类型和约束规则的 schema

  • 验证数据并定位问题

  • 清洗数据以符合 schema

  • 再次验证清洗后的数据

  • 构建可复用的数据处理管道

Pandera 还支持更复杂的验证场景,例如基于类的 schema、跨字段校验、局部校验等,详情可参见官方 Pandera 文档。


http://www.hkcw.cn/article/iWJaoLgLhD.shtml

相关文章

【Java基础04】方法

文章目录 1 方法概述1.1 方法的概念和格式1.2 方法的调用1.3 方法的重载1.4 方法的内存 部分参考 这篇博客 1 方法概述 1.1 方法的概念和格式 方法&#xff08;method&#xff09;是程序中最小的执行单元。 将重复的代码打包&#xff0c;避免重复度过高&#xff0c;复用性差…

欧冠夺冠巴黎街头乱成一锅粥:汽车被烧 大批球迷冲击警察 294人被捕

巴黎圣日耳曼在欧冠决赛中以5-0战胜国际米兰,队史首次夺得欧洲冠军。这一胜利让慕尼黑的巴黎球迷和法国首都巴黎的庆祝活动同时开启。然而,庆祝活动中爆发了多起冲突事件。法国内政部长布鲁诺-勒泰约在社交平台上发文表示,真正的巴黎球迷正在为球队的精彩表现欢呼,而一些人…

特朗普不要的中国留学生 全球抢着要 各国高校纷纷伸出橄榄枝

美国政府宣布将吊销中国学生签证,并指示海外使领馆暂停新学生签证预约。这一消息引起了国际社会的广泛关注和批评。世界各地的高校迅速采取行动,试图吸引受影响的学生。美国国务卿在国务院官网上发表声明称,美国国务院将开始大力撤销中国留学生的签证,尤其是那些在关键领域…

中国造船业全球第一!有订单排至2029年 市场韧性强劲

在全球贸易形势复杂多变的情况下,中国的造船产业展现了强大的市场韧性和竞争力。今年1-4月,中国造船产业新接订单量占世界市场份额继续保持全球第一。许多造船企业订单充足,生产任务已经排到了几年之后。下午三点,在辽宁大连的一家造船企业码头上,一艘16000标箱的集装箱船…

樊振东6月仍会出战中国乒超 加盟德甲引发关注

6月1日,德国萨尔布吕肯乒乓球甲级俱乐部宣布樊振东将在下赛季加盟。这一消息迅速引发广泛关注。截至当天中午12时,该俱乐部微博账号的转评赞总数达到6.1万,其中关于樊振东加盟的消息转评赞就超过了5.9万。樊振东在官宣消息中表示,他非常期待在萨尔布吕肯和德甲的新挑战,体…

自定义Spring Boot Starter

自定义Spring Boot Starter 1.引入依赖2.配置属性类3.业务服务类4.创建自动配置类5.注册自动配置6.案例使用6.1 引入依赖6.2 手动引入jar包6.3 yml中配置6.4 实际使用 7.包结构 1.引入依赖 <packaging>jar</packaging><dependencies><!-- Spring Boot 自动…

5名中国公民在美国遇难 警方回应 酒驾酿悲剧

美国警方于5月30日表示,在5月初黄石国家公园附近发生的致7人死亡的交通事故中,肇事皮卡司机的血液酒精含量超过法定驾驶限值的两倍。这起事故发生在当地时间5月1日晚,地点在美国爱达荷州黄石国家公园附近。事故造成7人死亡、多人受伤。中国驻旧金山总领馆在5月2日确认,死者…

云南雨崩遭遇强降雨关闭景区 游客被困村内

5月31日,云南德钦梅里雪山国家公园开发经营有限公司发布公告称,近期德钦境内遭遇极端天气持续强降雨,雨崩和明永景区部分游览线路区域极易产生山体滑坡、泥石流及塌方,地质灾害风险等级较高,存在极大安全隐患。决定自2025年5月31日起,两景区临时闭园,具体开放时间另行通…

《人民的名义》“孙连城”带货望远镜 从“宇宙区长”到直播达人

5月31日晚,曾在热播电视剧《人民的名义》中饰演“懒政区长孙连城”的演员李威,在短视频平台开启直播带货,所售商品为天文望远镜。近一周内,李威已进行了三场相关直播。然而,6月1日上午,其发布的直播预告视频疑似被隐藏或删除,商品橱窗中的天文望远镜也已清空。在剧中,孙…

左玮:“怎么养都不对”的迷茫,或许来自当下最分裂的教养方式 离知识最近,离生活最远

儿童节之际,祝所有小朋友节日快乐。然而,在庆祝的同时,我们也应反思孩子们是否真的快乐,成长的快乐到底是什么样的。最近,四川大学华西医院儿童心理卫生中心自2023年4月正式揭牌后,使用率一直保持在100%,许多孩子和家长还在排队等待入院。社区心理服务点的心理咨询师同样…

Python实现P-PSO优化算法优化循环神经网络LSTM回归模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在当今数据驱动的时代&#xff0c;时间序列预测和回归分析是许多领域中不可或缺的技术手段。循环神经网络&#xff…

重庆田野公司购销穿山甲制品案宣判 多家药企涉罪免罚

因从重庆田野药业有限公司购买中药饮片炮山甲并进行销售,2019年,四川省简阳市医药有限责任公司、四川省东宇药业有限公司等多家药企均被四川省内江市公安机关立案调查。炮山甲是经炮制的穿山甲鳞片,曾作为中药饮片载入2015年版《中国药典》,但在2020年版《中国药典》中被除…

大巴黎55年首捧欧冠奖杯该感谢谁 恩里克带来转机

即便是强队和弱旅之间的对决,5比0的结果也足够说明问题,更何况是一场欧冠决赛。大巴黎的球迷无疑是幸福的,这支成立于1970年的法甲豪门终于在第17次征战欧冠时拿到了首座冠军奖杯,他们以5比0横扫意甲的国际米兰,创下最大分差纪录。说到法甲联赛,大巴黎是特殊的存在。相比…

(11)课29--30:navicat 的用法;行转列的查询与典型算法,并涉及分组(学生各科成绩与比赛胜负);

&#xff08;48&#xff09; 查询的大例题 &#xff1a; &#xff08;49&#xff09;再举一例 &#xff1a; &#xff08;50&#xff09; 谢谢

巴黎主帅说会把金球奖颁给登贝莱 赞誉其决赛表现

巴黎圣日耳曼在欧冠决赛中以5-0战胜国际米兰,成功夺冠并加冕三冠王。赛后,主教练恩里克出席了新闻发布会。恩里克表示,比赛前的紧张氛围让他难以确切定义这场比赛。他认为球队很好地进入了比赛状态,并且在赛前一周的训练中保持了良好的精神状态。比赛中,球队展现了极高的强…

潘展乐2009年童年照 你能认出他吗?

6月1日,适逢国际儿童节,世界泳联更新了几位游泳运动员的童年照,称都是大家熟悉的运动员,谁能一眼认出他们是谁!你能猜出来他们是谁吗?责任编辑:zhangxiaohua

中国乒协支持樊振东加盟德甲 备战新赛程

6月1日,德甲萨尔布吕肯俱乐部通过社交媒体宣布中国运动员樊振东加盟该俱乐部,将参与2025-2026赛季德国乒乓球甲级联赛和欧洲冠军联赛。樊振东目前仍处在奥运后的调整期,计划通过全国比赛及国内外俱乐部比赛逐步恢复运动状态。中国乒协表示理解和尊重樊振东的意愿,并将全力支…

上海个人养老金人均缴存额全国第一 政策激发市民热情

个人养老金制度是完善多层次养老保险体系的重要措施,通过政策引导与市场机制结合,为市民提供了补充养老储备的灵活选择。截至2025年4月,上海地区个人养老金累计缴存金额超过180亿元,位居全国前列,人均缴存额约1万元,居全国第一。个人养老金每年缴费上限为12000元。对于不…

湖南14岁少年智救落水女子 冷静施救展现智慧勇气

5月29日,长沙浏阳市金刚中学收到一段目击者拍摄的救援视频,九年级2202班学生蔡桃红见义勇为的事迹逐渐为人知晓。这位14岁的少年依靠在学校学到的防溺水知识,挽救了一条生命。5月28日清晨,蔡桃红与父亲途经太子湖桥时,突然听到桥下传来急促的呼救声。他们发现一名女子在湖…

樊振东还会参加今年乒超联赛吗 确定参加前两阶段

北京时间6月1日,德国乒乓球甲级联赛FC萨尔布吕肯俱乐部宣布奥运冠军樊振东加盟。这一消息让球迷们非常关心他是否还能参加本赛季的乒超联赛。上海市乒羽中心透露,樊振东将参加乒超第一和第二阶段的比赛。中国乒乓球协会在5月28日公布了2025赛季中国乒乓球俱乐部超级联赛的赛程…