8、Python ETL基础:Python环境搭建、Pandas库入门、DataFrame操作、数据读写(CSV/Excel/DB)

说实话,很多刚入行的朋友问我:“ETL到底用什么语言最合适?”我的答案永远是Python。为什么?因为Python在数据处理这块,生态太强了。尤其是Pandas这个库,简直就是为ETL工程师量身定做的。今天我就带你把这套环境搭起来,再上手玩转DataFrame。

8.1 Python环境搭建:别小看这一步

我见过太多人卡在环境搭建上。其实没那么复杂,但有几个坑你得避开。

8.1.1 安装Python解释器

我个人习惯用Python 3.8+版本。别用2.x了,那都是老黄历。去官网下载安装包,记得勾选“Add Python to PATH”。嗯,这一步很多人会忘,结果命令行里打python没反应。

8.1.2 虚拟环境:隔离才是王道

你想想看,一个项目用Pandas 1.3,另一个用2.0,冲突了怎么办?虚拟环境就是干这个的。

# 创建虚拟环境
python -m venv etl_env

# 激活(Windows)
etl_env\Scripts\activate

# 激活(Mac/Linux)
source etl_env/bin/activate
我的习惯:每个ETL项目都建一个独立的虚拟环境。曾经有一次,我在生产环境直接装包,结果把依赖搞崩了...从那以后,虚拟环境成了我的铁律。

8.1.3 安装Pandas及相关库

pip install pandas numpy openpyxl sqlalchemy pymysql

这里openpyxl是用来读写Excel的,sqlalchemy是连接数据库的桥梁。别漏了。

8.2 Pandas库入门:你每天都在用的瑞士军刀

Pandas的核心就两个东西:Series(一维)和DataFrame(二维)。做ETL的,天天跟DataFrame打交道。

8.2.1 导入Pandas

import pandas as pd
import numpy as np

这几乎是每段代码的开头。我习惯把np也带上,有时候处理空值要用到。

8.2.2 创建DataFrame的几种方式

从字典创建是最常见的:

data = {
    '姓名': ['张三', '李四', '王五'],
    '年龄': [28, 32, 25],
    '部门': ['技术部', '市场部', '技术部']
}
df = pd.DataFrame(data)
print(df)

从列表创建也行:

df = pd.DataFrame([
    ['张三', 28, '技术部'],
    ['李四', 32, '市场部'],
    ['王五', 25, '技术部']
], columns=['姓名', '年龄', '部门'])
重点:实际ETL中,数据很少手动创建。都是从文件或数据库读进来的。但理解这两种方式,能帮你快速测试逻辑。

8.3 DataFrame操作:ETL的核心战场

DataFrame的操作,说白了就是增删改查。但ETL里,我们更关注筛选、聚合、连接这些操作。

8.3.1 查看数据概览

# 看前5行
df.head()

# 看基本信息
df.info()

# 看统计摘要
df.describe()

拿到数据第一件事,我就是跑info()。看看有没有空值,数据类型对不对。有一次我发现“年龄”列竟然是字符串,就是因为先跑了info()才发现的。

8.3.2 筛选与切片

# 筛选年龄大于30的
df[df['年龄'] > 30]

# 多条件筛选
df[(df['年龄'] > 25) & (df['部门'] == '技术部')]

# 选特定列
df[['姓名', '部门']]

8.3.3 处理空值

空值是ETL里最头疼的问题之一。我的处理原则是:能不删就不删,能填充就填充。

# 检查空值
df.isnull().sum()

# 删除空值行
df.dropna()

# 填充空值
df.fillna({'年龄': df['年龄'].mean()})
注意:dropna()默认会删除任何包含空值的行。我曾经在项目里直接用了dropna(),结果删掉了大半数据...后来才知道,可以加subset参数指定列。

8.3.4 分组与聚合

# 按部门分组,计算平均年龄
df.groupby('部门')['年龄'].mean()

# 多个聚合函数
df.groupby('部门').agg({'年龄': ['mean', 'max', 'min']})

8.4 数据读写:CSV/Excel/DB

ETL嘛,E(抽取)和L(加载)都离不开读写操作。我按常见的数据源给你捋一遍。

8.4.1 CSV文件读写

CSV是最通用的格式,几乎每个系统都支持。

# 读取CSV
df = pd.read_csv('data.csv', encoding='utf-8')

# 写入CSV
df.to_csv('output.csv', index=False, encoding='utf-8-sig')

注意encoding参数。utf-8-sig可以解决Excel打开乱码的问题。这个坑我踩过好几次。

8.4.2 Excel文件读写

# 读取Excel
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')

# 写入Excel
with pd.ExcelWriter('output.xlsx') as writer:
    df.to_excel(writer, sheet_name='清洗后数据', index=False)
小技巧:ExcelWriter可以写多个sheet。我经常把原始数据、清洗后数据、异常数据分别写到不同sheet里,方便核对。

8.4.3 数据库读写

这才是ETL的重头戏。我们用SQLAlchemy连接数据库。

from sqlalchemy import create_engine

# 连接MySQL
engine = create_engine('mysql+pymysql://用户名:密码@主机:端口/数据库名')

# 从数据库读取
df = pd.read_sql('SELECT * FROM users', engine)

# 写入数据库
df.to_sql('users_clean', engine, if_exists='replace', index=False)

if_exists参数有三个选项:fail(表存在就报错)、replace(替换)、append(追加)。我一般用append做增量加载,用replace做全量刷新。

8.5 本章知识体系总览

下面这张图,是我梳理的Python ETL基础核心脉络。你看一遍,心里就有谱了。

Python ETL基础核心脉络 Python ETL 基础 环境搭建 Python 3.8+ 虚拟环境 venv pip install pandas Pandas入门 Series / DataFrame 从字典/列表创建 head() / info() / describe() DataFrame操作 筛选 / 切片 空值处理 dropna/fillna 分组聚合 groupby 数据读写(CSV / Excel / DB) CSV: read_csv / to_csv Excel: read_excel / ExcelWriter DB: read_sql / to_sql SQLAlchemy引擎 掌握这些,ETL基础就稳了

8.6 避坑指南:我踩过的那些坑

  • 编码问题:CSV文件用Excel打开乱码?试试encoding='utf-8-sig'。我因为这个被业务部门投诉过两次。
  • 大文件读取:别直接用read_csv读几个G的文件。用chunksize参数分块读,或者用dtype指定列类型减少内存。
  • 数据库连接池:频繁创建数据库连接很慢。用create_engine时加上pool_size=5,复用连接。
  • 索引陷阱:to_csv时记得加index=False,不然会多出一列索引。我第一次写ETL脚本就犯了这错。

总结一下:Python ETL基础,说白了就是三件事——搭好环境、玩转DataFrame、搞定读写。环境是地基,DataFrame是工具,读写是接口。这三样拿下了,后面学什么高级ETL框架都不慌。

我个人建议,新手先别急着学Airflow、Spark那些。把Pandas的DataFrame操练熟,能处理80%的ETL场景。剩下的20%,等你遇到再说。


公众号:蓝海资料掘金营,微信deep3321