哪些Python案例展示了pandas用法?

wen python案例 1

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的精髓。

哪些Python案例展示了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 可选 innerleftrightouter,注意:默认是内连接,会丢失不匹配的行。


⏰ 案例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.splitexpand=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 降序。rankmethod 可选 average(第1,2名并列则分别1.5)、mindense(连续排不跳号)。


🛠 案例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 对于元素有限的字符串列(城市、性别等)可大幅减少内存。


❓ 问答环节(精选高频问题)

Q1read_csv 遇到编码错误怎么办?
A1:先试 encoding='utf-8',不行换 gbkgb2312latin1,或者用 chardet 库自动检测。

Q2groupby 后为什么有的列没了?
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,需安装 openpyxlxlrd


写在最后

15个案例覆盖了Pandas从数据导入、清洗、转换、聚合到可视化的完整链路,每一个都是你在实际工作中至少会遇到一次的经典场景,Pandas学习没有捷径,就是多看真实案例 + 动手敲代码,如果你把每个案例的代码在Jupyter里跑一遍,并随机换一批数据测试,一周内就能真正上手。

希望这篇文章对你有用,如果你有更复杂的场景,欢迎在评论区留言,我会精选案例继续补充。

抱歉,评论功能暂时关闭!