一、petl库基础认知
petl全称为Python ETL,是一款专注于轻量级数据提取、转换、加载的开源Python库,核心面向表格型数据处理场景,无需依赖 heavy 框架即可完成数据清洗、筛选、合并、格式转换等操作。其工作原理是通过惰性加载处理数据,仅在需要输出时才执行计算,大幅降低内存占用。该库采用MIT开源许可,优点是轻量简洁、上手门槛低、适合中小数据集处理,缺点是不适合超大规模分布式数据运算,性能弱于Pandas等专业数据分析库。

二、petl库安装方法
petl的安装流程十分简便,支持pip快速安装,无需配置复杂环境,适合Python初学者直接使用。
打开命令行工具,执行以下安装命令:
pip install petl
若需要加速安装,可使用国内镜像源:
pip install petl -i https://pypi.tuna.tsinghua.edu.cn/simple
安装完成后,在Python脚本中直接导入即可验证是否安装成功:
import petl
print(petl.__version__)
执行后输出版本号,即代表安装完成,可以正常使用。
三、petl核心数据结构与基础操作
petl核心围绕表格数据展开,其数据结构可以是列表、元组、CSV文件、Excel文件、数据库查询结果等,所有操作均以行和列为基本单位,语法贴近自然语言,极易理解。
3.1 创建基础表格数据
petl可以直接从Python原生数据结构创建数据表,这是入门的第一步。
import petl as etl
# 手动创建表格数据,第一行为表头,后续为数据行
table = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海'],
['王五', 28, '深圳'],
['赵六', 24, '广州']
]
# 查看数据前3行
print(etl.head(table, 3))
代码说明:
- 导入petl库并简写为etl,方便后续调用;
- 使用列表嵌套结构定义表格,第一行是字段名,后续每行是一条数据;
- head()方法用于查看指定行数的数据,默认查看前5行,此处指定查看前3行,方便快速预览数据结构。
3.2 数据筛选与条件查询
数据筛选是数据处理中最常用的功能,petl提供select、selecteq、selectne等方法实现条件过滤。
import petl as etl
table = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海'],
['王五', 28, '深圳'],
['赵六', 24, '广州']
]
# 筛选年龄大于24岁的数据
age_filter = etl.select(table, lambda rec: rec.age > 24)
print('年龄大于24岁的数据:')
print(age_filter)
# 筛选城市为上海的数据
city_filter = etl.selecteq(table, 'city', '上海')
print('\n城市为上海的数据:')
print(city_filter)
代码说明:
- select()方法支持自定义lambda函数,可实现复杂条件筛选;
- selecteq()是等值筛选方法,直接指定字段和对应值即可,语法更简洁;
- 所有操作返回新的表格对象,不会修改原始数据,保证数据安全。
3.3 字段新增与修改
处理数据时经常需要新增计算字段或修改现有字段,petl的addfield()和convert()方法可快速实现。
import petl as etl
table = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海'],
['王五', 28, '深圳'],
['赵六', 24, '广州']
]
# 新增年龄分组字段
table_add = etl.addfield(table, 'age_group', lambda rec: '青年' if rec.age < 25 else '壮年')
print('新增年龄分组字段后:')
print(table_add)
# 修改年龄字段,所有年龄+1
table_convert = etl.convert(table_add, 'age', lambda v: v + 1)
print('\n修改年龄字段后:')
print(table_convert)
代码说明:
- addfield()用于新增字段,可通过lambda函数根据现有数据计算新字段值;
- convert()用于修改指定字段的值,支持批量转换、格式调整等操作;
- 操作支持链式调用,可连续对数据进行处理。
3.4 数据排序与去重
数据排序和去重是数据清洗的必备环节,petl提供sort()、distinct()方法快速处理。
import petl as etl
table = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海'],
['张三', 22, '北京'],
['王五', 28, '深圳'],
['赵六', 24, '广州']
]
# 数据去重
table_distinct = etl.distinct(table)
print('去重后的数据:')
print(table_distinct)
# 按年龄降序排序
table_sort = etl.sort(table_distinct, key='age', reverse=True)
print('\n按年龄降序排序后:')
print(table_sort)
代码说明:
- distinct()方法会自动去除完全重复的数据行;
- sort()方法通过key指定排序字段,reverse=True表示降序,False为升序;
- 处理后的数据结构保持不变,可直接用于后续操作。
四、petl文件读写操作
petl最大的优势之一是支持多种文件格式的读写,包括CSV、Excel、JSON、HTML等,无需依赖其他库即可完成文件数据处理。
4.1 CSV文件读写
CSV是最常用的表格数据格式,petl对CSV的支持极为完善,读写速度快且稳定。
import petl as etl
# 定义测试数据
table = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海'],
['王五', 28, '深圳'],
['赵六', 24, '广州']
]
# 将数据写入CSV文件
etl.tocsv(table, 'user_data.csv', encoding='utf-8')
print('数据已写入CSV文件')
# 从CSV文件读取数据
read_csv = etl.fromcsv('user_data.csv', encoding='utf-8')
print('\n读取CSV文件数据:')
print(etl.head(read_csv))
代码说明:
- tocsv()方法将petl表格数据写入CSV文件,需指定编码格式避免中文乱码;
- fromcsv()方法读取CSV文件并转换为petl可处理的表格对象;
- 支持指定分隔符、是否包含表头等参数,适配不同格式的CSV文件。
4.2 Excel文件读写
petl读写Excel文件需要依赖openpyxl或xlrd库,需提前安装依赖:
pip install openpyxl xlrd
安装完成后执行读写代码:
import petl as etl
table = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海'],
['王五', 28, '深圳'],
['赵六', 24, '广州']
]
# 写入Excel文件
etl.toxlsx(table, 'user_data.xlsx', sheet='用户信息')
print('数据已写入Excel文件')
# 读取Excel文件
read_excel = etl.fromxlsx('user_data.xlsx', sheet='用户信息')
print('\n读取Excel文件数据:')
print(etl.head(read_excel))
代码说明:
- toxlsx()和fromxlsx()分别实现Excel文件的写入和读取;
- 支持指定sheet工作表名称,适合处理多工作表的Excel文件;
- 读取后的数据格式与手动创建的表格数据一致,可直接使用所有petl操作方法。
4.3 JSON与HTML格式数据处理
除了常规表格文件,petl还支持JSON和HTML格式的数据转换,适合数据展示和接口对接。
import petl as etl
table = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海'],
['王五', 28, '深圳']
]
# 转换为JSON格式
json_data = etl.tojson(table)
print('JSON格式数据:')
print(json_data)
# 转换为HTML表格
html_table = etl.tohtml(table)
print('\nHTML表格代码:')
print(html_table)
代码说明:
- tojson()将表格数据转换为JSON格式,适合接口数据返回;
- tohtml()将数据转换为HTML表格代码,可直接嵌入网页展示;
- 转换过程自动保留字段名和数据对应关系,无需手动格式化。
五、petl数据合并与关联操作
在实际数据处理中,经常需要将多个数据源合并、关联,petl提供cat、join、lookup等方法实现多表操作,功能媲美数据库关联查询。
5.1 多表数据合并
cat()方法用于将结构相同的多个表格合并为一个表格,适合数据拼接场景。
import petl as etl
# 定义两个结构相同的表格
table1 = [
['name', 'age', 'city'],
['张三', 22, '北京'],
['李四', 25, '上海']
]
table2 = [
['name', 'age', 'city'],
['王五', 28, '深圳'],
['赵六', 24, '广州']
]
# 合并两个表格
merge_table = etl.cat(table1, table2)
print('合并后的数据:')
print(merge_table)
代码说明:
- cat()方法可接收多个表格参数,一次性合并多个数据源;
- 要求表格的字段结构完全一致,否则会出现数据错位;
- 合并后保留所有数据行,不进行去重操作,如需去重可配合distinct()使用。
5.2 表关联查询(join)
join()方法实现类似数据库的左连接、内连接,适合多表关联分析。
import petl as etl
# 用户基础信息表
user_table = [
['user_id', 'name'],
[1, '张三'],
[2, '李四'],
[3, '王五']
]
# 用户订单表
order_table = [
['user_id', 'order_no', 'amount'],
[1, 'ORDER001', 99],
[2, 'ORDER002', 199],
[1, 'ORDER003', 299]
]
# 内连接:只保留匹配的数据
inner_join = etl.join(user_table, order_table, key='user_id')
print('内连接结果:')
print(inner_join)
# 左连接:保留左表所有数据
left_join = etl.leftjoin(user_table, order_table, key='user_id')
print('\n左连接结果:')
print(left_join)
代码说明:
- key参数指定关联字段,通常为ID类唯一标识;
- 内连接只保留两张表都存在的匹配数据;
- 左连接保留左表所有数据,右表无匹配数据时填充为None;
- 无需编写复杂SQL,纯Python语法即可实现数据库级别的关联查询。
六、petl与数据库交互
petl支持直接连接MySQL、SQLite、PostgreSQL等数据库,实现数据的提取与写入,是ETL流程的核心功能。
6.1 SQLite数据库操作
SQLite为轻量级文件数据库,无需单独安装服务,适合演示。
import petl as etl
import sqlite3
# 连接SQLite数据库
conn = sqlite3.connect('test.db')
# 创建测试表
conn.execute('''CREATE TABLE IF NOT EXISTS user
(id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')
# 定义数据并写入数据库
table = [
['id', 'name', 'age'],
[1, '张三', 22],
[2, '李四', 25],
[3, '王五', 28]
]
etl.todb(table, conn, 'user')
print('数据已写入SQLite数据库')
# 从数据库读取数据
db_table = etl.fromdb(conn, 'SELECT * FROM user')
print('\n从数据库读取的数据:')
print(db_table)
conn.close()
代码说明:
- fromdb()从数据库执行SQL查询并返回petl表格数据;
- todb()将petl数据写入数据库表;
- 支持事务操作、批量写入,效率高于原生Python数据库操作。
6.2 MySQL数据库操作
连接MySQL需要安装pymysql库:
pip install pymysql
连接代码:
import petl as etl
import pymysql
# 连接MySQL数据库
conn = pymysql.connect(
host='localhost',
user='root',
password='123456',
database='test_db',
charset='utf8'
)
# 从MySQL查询数据
mysql_table = etl.fromdb(conn, 'SELECT name, age FROM user LIMIT 5')
print('MySQL数据:')
print(mysql_table)
conn.close()
代码说明:
- 连接参数需根据实际MySQL环境修改;
- 支持复杂SQL查询,结果直接转换为petl可处理的表格;
- 可实现数据从数据库提取→清洗→转换→写回数据库的完整ETL流程。
七、petl实际业务案例
以用户数据清洗与分析为例,模拟真实业务场景,整合petl所有核心操作。
7.1 业务需求
- 读取CSV格式的原始用户数据;
- 去除重复数据、空值数据;
- 筛选年龄在20-30岁之间的用户;
- 新增年龄段分组字段;
- 按城市统计用户数量;
- 将处理结果保存为Excel文件。
7.2 完整实现代码
import petl as etl
# 1. 读取原始CSV数据
raw_data = etl.fromcsv('raw_user.csv', encoding='utf-8')
# 2. 去除重复数据和空值数据
data_no_dup = etl.distinct(raw_data)
data_no_null = etl.rejectmissing(data_no_dup)
# 3. 筛选年龄20-30岁的用户
data_filter = etl.select(data_no_null, lambda rec: 20 <= int(rec.age) <= 30)
# 4. 新增年龄段分组字段
data_add_field = etl.addfield(data_filter, 'age_group',
lambda rec: '20-25岁' if 20 <= int(rec.age) <=25 else '26-30岁')
# 5. 按城市统计用户数量
city_stats = etl.aggregate(data_add_field, 'city', count=('name', len))
# 6. 保存处理后的数据和统计结果
etl.toxlsx(data_add_field, 'clean_user_data.xlsx', sheet='清洗后数据')
etl.toxlsx(city_stats, 'city_user_stats.xlsx', sheet='城市统计')
print('数据处理完成,结果已保存为Excel文件')
代码说明:
- rejectmissing()方法自动剔除包含空值的数据行,保证数据质量;
- aggregate()实现分组统计功能,类似SQL的GROUP BY,可统计数量、求和、平均值等;
- 整个流程采用链式处理逻辑,代码简洁易读,无需创建中间变量;
- 从文件读取到最终输出,全程使用petl完成,适合自动化数据处理脚本。
相关资源
- Pypi地址:https://pypi.org/project/petl
- Github地址:https://github.com/petl-developers/petl
- 官方文档地址:https://petl.readthedocs.io/
关注我,每天分享一个实用的Python自动化工具。









