Python实用数据处理库petl:轻量级表格数据操作完全指南

一、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))

代码说明:

  1. 导入petl库并简写为etl,方便后续调用;
  2. 使用列表嵌套结构定义表格,第一行是字段名,后续每行是一条数据;
  3. 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)

代码说明:

  1. select()方法支持自定义lambda函数,可实现复杂条件筛选;
  2. selecteq()是等值筛选方法,直接指定字段和对应值即可,语法更简洁;
  3. 所有操作返回新的表格对象,不会修改原始数据,保证数据安全。

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)

代码说明:

  1. addfield()用于新增字段,可通过lambda函数根据现有数据计算新字段值;
  2. convert()用于修改指定字段的值,支持批量转换、格式调整等操作;
  3. 操作支持链式调用,可连续对数据进行处理。

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)

代码说明:

  1. distinct()方法会自动去除完全重复的数据行;
  2. sort()方法通过key指定排序字段,reverse=True表示降序,False为升序;
  3. 处理后的数据结构保持不变,可直接用于后续操作。

四、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))

代码说明:

  1. tocsv()方法将petl表格数据写入CSV文件,需指定编码格式避免中文乱码;
  2. fromcsv()方法读取CSV文件并转换为petl可处理的表格对象;
  3. 支持指定分隔符、是否包含表头等参数,适配不同格式的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))

代码说明:

  1. toxlsx()和fromxlsx()分别实现Excel文件的写入和读取;
  2. 支持指定sheet工作表名称,适合处理多工作表的Excel文件;
  3. 读取后的数据格式与手动创建的表格数据一致,可直接使用所有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)

代码说明:

  1. tojson()将表格数据转换为JSON格式,适合接口数据返回;
  2. tohtml()将数据转换为HTML表格代码,可直接嵌入网页展示;
  3. 转换过程自动保留字段名和数据对应关系,无需手动格式化。

五、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)

代码说明:

  1. cat()方法可接收多个表格参数,一次性合并多个数据源;
  2. 要求表格的字段结构完全一致,否则会出现数据错位;
  3. 合并后保留所有数据行,不进行去重操作,如需去重可配合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)

代码说明:

  1. key参数指定关联字段,通常为ID类唯一标识;
  2. 内连接只保留两张表都存在的匹配数据;
  3. 左连接保留左表所有数据,右表无匹配数据时填充为None;
  4. 无需编写复杂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()

代码说明:

  1. fromdb()从数据库执行SQL查询并返回petl表格数据;
  2. todb()将petl数据写入数据库表;
  3. 支持事务操作、批量写入,效率高于原生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()

代码说明:

  1. 连接参数需根据实际MySQL环境修改;
  2. 支持复杂SQL查询,结果直接转换为petl可处理的表格;
  3. 可实现数据从数据库提取→清洗→转换→写回数据库的完整ETL流程。

七、petl实际业务案例

用户数据清洗与分析为例,模拟真实业务场景,整合petl所有核心操作。

7.1 业务需求

  1. 读取CSV格式的原始用户数据;
  2. 去除重复数据、空值数据;
  3. 筛选年龄在20-30岁之间的用户;
  4. 新增年龄段分组字段;
  5. 按城市统计用户数量;
  6. 将处理结果保存为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文件')

代码说明:

  1. rejectmissing()方法自动剔除包含空值的数据行,保证数据质量;
  2. aggregate()实现分组统计功能,类似SQL的GROUP BY,可统计数量、求和、平均值等;
  3. 整个流程采用链式处理逻辑,代码简洁易读,无需创建中间变量;
  4. 从文件读取到最终输出,全程使用petl完成,适合自动化数据处理脚本。

相关资源

  • Pypi地址:https://pypi.org/project/petl
  • Github地址:https://github.com/petl-developers/petl
  • 官方文档地址:https://petl.readthedocs.io/

关注我,每天分享一个实用的Python自动化工具。