15个真实Python案例,彻底掌握Pandas核心用法
📚 目录导读
- 案例1:数据加载与初步探索(read_csv + info/describe)
- 案例2:数据清洗实战(缺失值处理、去重)
- 案例3:数据筛选与过滤(布尔索引 + query)
- 案例4:数据分组与聚合(groupby + agg)
- 案例5:多列运算与apply应用
- 案例6:数据合并与连接(merge/join/concat)
- 案例7:时间序列处理(to_datetime + resample)
- 案例8:数据透视表(pivot_table)
- 案例9:列拆分与文本处理(str.split/extract)
- 案例10:数据排序与排名(sort_values + rank)
- 案例11:条件批量修改(np.where / loc)
- 案例12:分层索引与stack/unstack
- 案例13:数据可视化底座(plot + 统计图)
- 案例14:大数据分块处理(chunksize)
- 案例15:性能优化小技巧(向量化 vs 循环)
引言:为什么Pandas是数据分析师的第一把吉他?
Pandas是Python数据分析生态中最核心的库之一,它提供了高效、直观的数据结构(Series和DataFrame)以及大量便捷的数据操作函数,无论是清洗脏数据、合并多个表格,还是做复杂的分组统计,Pandas都能用几行代码搞定,但很多初学者看完文档仍觉得“会函数但不会用”,所以本文挑选了15个真实业务场景中的经典案例,每个案例都包含问题描述、代码实现和解析,帮助你真正掌握Pandas的精髓。

🔍 案例1:数据加载与初步探索
问题:你从网站下载了销售数据(CSV格式),需要快速了解表结构、列类型、缺失情况、数值分布。
import pandas as pd
df = pd.read_csv('sales_data.csv', parse_dates=['订单日期'], encoding='utf-8')
print(df.info()) # 列名、非空计数、数据类型
print(df.describe()) # 数值列的均值、标准差、四分位数
print(df.head(3)) # 前3行,确认数据样子
解析:info() 会告诉你哪些列有缺失值(非空数<行数),describe() 可快速发现异常极值(比如负价格),这是每个数据分析项目的第一步。
🧹 案例2:数据清洗实战
问题:数据中存在空值、重复行、以及“-”代替的缺失。
# 删除全为缺失的行
df.dropna(how='all', inplace=True)
# 用中位数填充年龄列缺失
df['年龄'].fillna(df['年龄'].median(), inplace=True)
# 删除重复行(保留第一个)
df.drop_duplicates(subset=['用户ID', '订单日期'], keep='first', inplace=True)
# 将带"-"的文本统一替换为NaN,再填充0
df['评分'].replace('-', pd.NA, inplace=True)
df['评分'] = df['评分'].fillna(0).astype(float)
解析:真实数据至少有20%的不规范,掌握缺失值三种处理(删除、填充、替代)是基本功,注意:不要轻易删除整行,先看看缺失比例。
🎯 案例3:数据筛选与过滤
问题:筛选出“北京地区、订单金额>500、并且订单状态为已完成”的数据。
# 方法1:布尔索引
filtered = df[(df['城市'] == '北京') & (df['金额'] > 500) & (df['状态'] == '已完成')]
# 方法2:query,更可读
filtered = df.query('城市 == "北京" and 金额 > 500 and 状态 == "已完成"')
解析:布尔索引速度快,适合简单条件;query 字符串写法更清晰,尤其条件多的时候,注意:字符串列一定要加引号。
📊 案例4:数据分组与聚合
问题:统计每个城市、每个月的销售额和订单数。
df['月份'] = df['订单日期'].dt.month
grouped = df.groupby(['城市', '月份']).agg(
销售额总和=('金额', 'sum'),
订单数=('订单ID', 'count'),
平均金额=('金额', 'mean')
).reset_index()
print(grouped)
解析:groupby + agg 是Pandas最强大的武器,可以同时计算多个聚合指标,注意 reset_index() 把分组键变回列,避免多层索引影响后续操作。
⚡ 案例5:多列运算与apply应用
问题:根据“单价”和“数量”计算“总价”,并给每个商品添加“价格档次”标签(高档/中档/低档)。
# 列运算(直接向量化,最快)
df['总价'] = df['单价'] * df['数量']
# 条件标签(使用apply)
def price_level(price):
if price > 100: return '高档'
elif price > 30: return '中档'
else: return '低档'
df['档次'] = df['单价'].apply(price_level)
解析:优先使用向量化运算(如 单价*数量),避免循环。apply 适合逻辑复杂的函数,但效率不如向量化,如果行数超过10万,可以考虑 np.select。
🔗 案例6:数据合并与连接
问题:有两个表——订单表(含用户ID)和用户信息表(含城市/年龄),需要按用户ID左连接。
merged = pd.merge(orders_df, users_df, on='用户ID', how='left') # 如果列名不同:left_on='user_id', right_on='uid' # 多键合并:on=['城市', '月份']
解析:merge 类似SQL的JOIN,how 可选 inner、left、right、outer,注意:默认是内连接,会丢失不匹配的行。
⏰ 案例7:时间序列处理
问题:用户购买记录(timestamp),按周统计购买次数,并发现周末是否订单更多。
df['购买日期'] = pd.to_datetime(df['购买时间']).dt.date
weekly = df.set_index('购买时间').resample('W')['订单ID'].count()
# 查看周几分布
df['星期几'] = df['购买时间'].dt.dayofweek # 0=周一
print(df['星期几'].value_counts().sort_index())
解析:resample 很棒,但必须先设时间列为索引。dt 访问器可以提取年/月/日/周几/季度等。
🧩 案例8:数据透视表
问题:做成行=城市、列=月份、值=销售额的矩阵。
pivot = pd.pivot_table(df, values='金额', index='城市', columns='月份', aggfunc='sum', fill_value=0)
解析:透视表是Excel高手的利器,Pandas实现更灵活。fill_value=0 避免NaN,你还可以加 margins=True 显示行/列总计。
✂️ 案例9:列拆分与文本处理
问题:一个“地址”列包含省、市、区,用逗号分隔,需要拆分开。
df[['省', '市', '区']] = df['地址'].str.split(',', expand=True)
# 或者用str.extract提取手机号
df['手机号'] = df['备注'].str.extract(r'(1[3-9]\d{9})')
解析:str.split 加 expand=True 直接把列表变成多列。str.extract 用正则提取匹配内容,非常实用。
📈 案例10:数据排序与排名
问题:按销售额降序排,并添加排名列(相同销售额并列同排名)。
df_sorted = df.sort_values('金额', ascending=False)
df_sorted['排名'] = df['金额'].rank(method='dense', ascending=False).astype(int)
解析:sort_values 默认升序,ascending=False 降序。rank 的 method 可选 average(第1,2名并列则分别1.5)、min、dense(连续排不跳号)。
🛠 案例11:条件批量修改
问题:根据金额区间,修改“评价”列:金额>300给“优质客户”,100-300给“普通客户”,否则“待激活”。
import numpy as np conditions = [df['金额'] > 300, df['金额'].between(100, 300)] choices = ['优质客户', '普通客户'] df['评价'] = np.select(conditions, choices, default='待激活')
解析:np.select 比嵌套 apply 快很多,适合多个条件且不用写函数,注意条件顺序:优先匹配第一个成立的。
🧠 案例12:分层索引与stack/unstack
问题:数据已经有二层索引(城市、月份),想转成宽表展示。
df_multi = df.set_index(['城市', '月份']) wide = df_multi.unstack(level='月份') # 月份升为列 # 或:long = wide.stack() # 变回长表
解析:分层索引虽然不常用,但遇到多层groupby结果做可视化时很方便。unstack 把行索引变成列,stack 反之。
📉 案例13:数据可视化底座
问题:快速画出各城市销售额柱状图。
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 显示中文
city_sales = df.groupby('城市')['金额'].sum().sort_values()
city_sales.plot(kind='barh', color='skyblue', figsize=(8,5))'各城市销售额')
plt.tight_layout()
plt.show()
解析:Pandas的 .plot 封装了matplotlib,一个 kind 参数就能切换折线图、柱状图、饼图、箱线图等,适合快速预览。
🚀 案例14:大数据分块处理
问题:10GB的CSV文件,内存不够一次性读取。
chunk_iter = pd.read_csv('large_file.csv', chunksize=50000)
results = []
for chunk in chunk_iter:
# 每块单独处理(比如筛选、聚合)
result = chunk[chunk['金额'] > 100].groupby('城市')['金额'].sum()
results.append(result)
final = pd.concat(results).groupby(level=0).sum()
解析:chunksize 返回迭代器,每次只加载指定行数,适合内存受限的机器,处理完合并时注意索引要一致。
⚙️ 案例15:性能优化小技巧
问题:觉得Pandas慢?试试这些技巧:
# 1. 使用向量化代替循环(快50倍+)
df['新列'] = df['A'] + df['B'] # 好
# for i in range(len(df)): # 差
# 2. 批量读取时指定列类型
df = pd.read_csv('data.csv', dtype={'用户ID': 'int32', '金额': 'float32'})
# 3. 使用category类型节省内存
df['城市'] = df['城市'].astype('category')
# 4. 用inplace=False但赋值(更好追踪副作用)
df = df.dropna() # 而不是 df.dropna(inplace=True)
解析:Pandas的慢多数是因为不当的循环或类型占用。category 对于元素有限的字符串列(城市、性别等)可大幅减少内存。
❓ 问答环节(精选高频问题)
Q1:read_csv 遇到编码错误怎么办?
A1:先试 encoding='utf-8',不行换 gbk、gb2312、latin1,或者用 chardet 库自动检测。
Q2:groupby 后为什么有的列没了?
A2:聚合函数会默认排除非数字列,可以在 agg 里指定列,或者用 groupby(...).as_index=False。
Q3:什么时候用 apply,什么时候用 transform?
A3:apply 返回一个标量或新的Series(降维),transform 返回与原始DataFrame相同形状的值(比如填充缺失值)。
Q4:如何加速多表连接(merge)?
A4:确保连接列是相同数据类型,可以提前排序或用索引连接;对于超大表,考虑用Dask或Modin。
Q5:Pandas是否支持MySQL、Excel?
A5:支持!read_sql + SQLAlchemy 连接数据库;read_excel 处理.xlsx,需安装 openpyxl 或 xlrd。
写在最后
15个案例覆盖了Pandas从数据导入、清洗、转换、聚合到可视化的完整链路,每一个都是你在实际工作中至少会遇到一次的经典场景,Pandas学习没有捷径,就是多看真实案例 + 动手敲代码,如果你把每个案例的代码在Jupyter里跑一遍,并随机换一批数据测试,一周内就能真正上手。
希望这篇文章对你有用,如果你有更复杂的场景,欢迎在评论区留言,我会精选案例继续补充。