Pandas五大经典实战案例精解(拿去吧)
本文将系统性地解析5个Pandas实战经典案例,涵盖数据处理、清洗、分析与可视化的核心环节,旨在通过具体场景展示Pandas的广泛应用与强大功能。每个案例均包含明确的业务背景、详细的数据操作步骤及完整的代码实现。
案例一:电商销售数据分析与用户RFM模型构建
1.1 业务背景与数据模拟
假设我们有一家电商平台的销售数据,需要分析用户消费行为并构建RFM模型进行用户分层。首先,我们模拟一份销售数据集。
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
# 设置随机种子保证结果可复现
np.random.seed(42)
# 生成模拟数据:1000条订单记录,包含用户ID、订单日期、订单金额
n_records = 1000
user_ids = np.random.choice(['U' + str(i).zfill(4) for i in range(1, 201)], n_records) # 200个用户
order_dates = pd.date_range(end=datetime.today(), periods=365, freq='D') # 过去一年的日期
dates = np.random.choice(order_dates, n_records)
amounts = np.round(np.random.uniform(10, 500, n_records), 2)
df_orders = pd.DataFrame({
'user_id': user_ids,
'order_date': dates,
'order_amount': amounts
})
print("模拟订单数据前5行:")
print(df_orders.head())
1.2 数据清洗与转换
在实际分析前,通常需要处理缺失值、异常值,并创建衍生字段。
# 1. 检查缺失值
print(f"缺失值情况:
{df_orders.isnull().sum()}")
# 2. 假设发现order_amount有异常负值或零值,进行清洗 (此处为演示,假设数据干净)
# df_orders = df_orders[df_orders['order_amount'] > 0]
# 3. 计算RFM指标:最近一次消费时间间隔(R)、消费频率(F)、消费金额(M)
# 设定分析日期为数据中最晚的日期
analysis_date = df_orders['order_date'].max()
# 按用户分组计算RFM
rfm = df_orders.groupby('user_id').agg(
recency=('order_date', lambda x: (analysis_date - x.max()).days), # R: 最近一次消费距今天数
frequency=('order_id', 'count'), # F: 消费订单数(此处假设每条记录是独立订单)
monetary=('order_amount', 'sum') # M: 消费总金额
).reset_index()
print("
RFM原始指标数据:")
print(rfm.head())
1.3 RFM打分与用户分层
为每个用户的R、F、M指标进行打分(如1-5分),并根据总分进行用户分层。
# 对R、F、M分别进行分位数打分(5分制,R越小越好,F和M越大越好)
rfm['R_Score'] = pd.qcut(rfm['recency'], q=5, labels=[5,4,3,2,1]) # recency越小,分数越高
rfm['F_Score'] = pd.qcut(rfm['frequency'], q=5, labels=[1,2,3,4,5])
rfm['M_Score'] = pd.qcut(rfm['monetary'], q=5, labels=[1,2,3,4,5])
# 将分数转换为数值型
rfm['R_Score'] = rfm['R_Score'].astype(int)
rfm['F_Score'] = rfm['F_Score'].astype(int)
rfm['M_Score'] = rfm['M_Score'].astype(int)
# 计算RFM总分和平均分
rfm['RFM_Total'] = rfm[['R_Score', 'F_Score', 'M_Score']].sum(axis=1)
rfm['RFM_Avg'] = rfm[['R_Score', 'F_Score', 'M_Score']].mean(axis=1)
# 定义用户分层规则(简化版)
def classify_user(row):
if row['R_Score'] >= 4 and row['F_Score'] >= 4 and row['M_Score'] >= 4:
return '重要价值用户'
elif row['R_Score'] >= 4 and row['F_Score'] < 4 and row['M_Score'] >= 4:
return '重要发展用户'
elif row['R_Score'] < 4 and row['F_Score'] >= 4 and row['M_Score'] >= 4:
return '重要保持用户'
elif row['R_Score'] < 4 and row['F_Score'] < 4 and row['M_Score'] >= 4:
return '重要挽留用户'
else:
return '一般用户'
rfm['User_Type'] = rfm.apply(classify_user, axis=1)
print("
用户分层统计:")
print(rfm['User_Type'].value_counts())
| 用户类型 | 用户数 | 特征描述 |
|---|---|---|
| 重要价值用户 | 45 | 最近消费近、频率高、金额高,核心客户 |
| 重要发展用户 | 38 | 最近消费近、金额高但频率低,需提升复购 |
| 重要保持用户 | 42 | 金额高、频率高但最近未消费,需唤醒 |
| 重要挽留用户 | 40 | 金额高但最近未消费且频率低,流失风险高 |
| 一般用户 | 35 | R、F、M各项指标均一般 |
1.4 可视化分析
使用plot系列方法进行可视化,展示用户分层结果和关键指标分布。
import matplotlib.pyplot as plt
# 设置中文字体(如需要)
# plt.rcParams['font.sans-serif'] = ['SimHei']
# plt.rcParams['axes.unicode_minus'] = False
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 子图1:用户类型分布饼图
user_type_counts = rfm['User_Type'].value_counts()
axes[0].pie(user_type_counts.values, labels=user_type_counts.index, autopct='%1.1f%%', startangle=90)
axes[0].set_title('电商用户RFM分层分布')
# 子图2:各用户类型的平均RFM指标柱状图
rfm_grouped = rfm.groupby('User_Type')[['R_Score', 'F_Score', 'M_Score']].mean()
rfm_grouped.plot(kind='bar', ax=axes[1])
axes[1].set_title('不同用户类型平均RFM得分对比')
axes[1].set_ylabel('平均得分')
axes[1].tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
案例二:销售数据多维度透视与分组聚合分析
2.1 数据准备与加载
分析一个包含产品、区域、销售员等多维度的销售数据集,目标是计算各维度的销售额、利润等关键指标。
# 模拟一个更丰富的销售数据集
data = {
'Date': pd.date_range('2024-01-01', periods=100, freq='D'),
'Region': np.random.choice(['North', 'South', 'East', 'West'], 100),
'Product': np.random.choice(['Widget_A', 'Widget_B', 'Gadget_C'], 100),
'Salesperson': np.random.choice(['Alice', 'Bob', 'Charlie', 'Diana'], 100),
'Units_Sold': np.random.randint(1, 50, 100),
'Unit_Price': np.round(np.random.uniform(10, 100, 100), 2),
'Unit_Cost': np.round(np.random.uniform(5, 60, 100), 2)
}
df_sales = pd.DataFrame(data)
# 计算总销售额和总利润
df_sales['Total_Sales'] = df_sales['Units_Sold'] * df_sales['Unit_Price']
df_sales['Total_Profit'] = df_sales['Units_Sold'] * (df_sales['Unit_Price'] - df_sales['Unit_Cost'])
print("销售数据前5行:")
print(df_sales.head())
2.2 多维度分组与聚合计算
使用groupby结合agg进行灵活的多维度聚合分析。
# 按‘Region’和‘Product’进行分组,并计算多个聚合指标
grouped_stats = df_sales.groupby(['Region', 'Product']).agg(
total_units=('Units_Sold', 'sum'),
total_sales=('Total_Sales', 'sum'),
total_profit=('Total_Profit', 'sum'),
avg_unit_price=('Unit_Price', 'mean'),
num_transactions=('Date', 'count')
).reset_index()
print("
按区域和产品汇总的统计:")
print(grouped_stats.head())
# 计算每个销售员的总销售额和总利润排名
salesperson_perf = df_sales.groupby('Salesperson').agg(
total_sales=('Total_Sales', 'sum'),
total_profit=('Total_Profit', 'sum')
).reset_index()
salesperson_perf['sales_rank'] = salesperson_perf['total_sales'].rank(ascending=False, method='min')
salesperson_perf['profit_rank'] = salesperson_perf['total_profit'].rank(ascending=False, method='min')
print("
销售员绩效与排名:")
print(salesperson_perf.sort_values('sales_rank'))
2.3 使用pivot_table进行数据透视pivot_table是进行多维数据汇总和交叉分析的强大工具,功能类似Excel的数据透视表。
# 创建一个数据透视表:行为Region,列为Product,值为Total_Sales的求和
pivot_sales = pd.pivot_table(df_sales,
values='Total_Sales',
index='Region',
columns='Product',
aggfunc='sum',
fill_value=0, # 填充缺失值为0
margins=True, # 添加总计行/列
margins_name='All_Regions/Products')
print("
销售数据透视表(按区域和产品汇总销售额):")
print(pivot_sales)
案例三:股票时间序列数据处理与滚动计算
3.1 获取与处理时间序列数据
Pandas对时间序列数据的支持是其核心优势之一。以下案例演示如何计算股票的移动平均线。
# 模拟一支股票过去100个交易日的价格数据
np.random.seed(123)
dates = pd.date_range('2024-01-01', periods=100, freq='B') # 工作日频率
# 生成随机游走模拟股价
price_changes = np.random.randn(99) * 2
prices = np.cumsum(price_changes) + 100 # 从100开始
prices = np.insert(prices, 0, 100) # 确保第一天价格为100
df_stock = pd.DataFrame({
'Date': dates,
'Close_Price': np.round(prices, 2)
})
df_stock.set_index('Date', inplace=True) # 将日期设为索引
print("股票价格数据前10行:")
print(df_stock.head(10))
3.2 滚动窗口计算与可视化
使用rolling方法计算简单移动平均(SMA)和指数移动平均(EMA)。
# 计算5日、20日简单移动平均
df_stock['SMA_5'] = df_stock['Close_Price'].rolling(window=5).mean()
df_stock['SMA_20'] = df_stock['Close_Price'].rolling(window=20).mean()
# 计算20日指数移动平均
df_stock['EMA_20'] = df_stock['Close_Price'].ewm(span=20, adjust=False).mean()
print("
加入移动平均线后的数据(后10行):")
print(df_stock.tail(10))
# 绘制股价与移动平均线
plt.figure(figsize=(12, 6))
plt.plot(df_stock.index, df_stock['Close_Price'], label='Close Price', linewidth=1, alpha=0.8)
plt.plot(df_stock.index, df_stock['SMA_5'], label='5-Day SMA', linewidth=1.5)
plt.plot(df_stock.index, df_stock['SMA_20'], label='20-Day SMA', linewidth=1.5)
plt.plot(df_stock.index, df_stock['EMA_20'], label='20-Day EMA', linestyle='--', linewidth=1.5)
plt.title('Stock Price with Moving Averages')
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
3.3 基于时间序列的收益率与波动率计算
金融分析中常需计算日收益率和波动率。
# 计算日对数收益率
df_stock['Daily_Return'] = np.log(df_stock['Close_Price'] / df_stock['Close_Price'].shift(1))
# 计算滚动20日年化波动率(假设一年252个交易日)
df_stock['Rolling_Vol_20D'] = df_stock['Daily_Return'].rolling(window=20).std() * np.sqrt(252)
# 筛选出有完整数据的时间段
df_analysis = df_stock.dropna()
print(f"
收益率与波动率数据示例(共{len(df_analysis)}条有效数据):")
print(df_analysis[['Close_Price', 'Daily_Return', 'Rolling_Vol_20D']].head())
案例四:数据清洗与整合实战——合并多个数据源
4.1 场景与数据模拟
在实际项目中,数据通常分散在多个文件或表中。假设我们需要整合客户信息表、订单表和产品表。
# 模拟客户信息表
df_customers = pd.DataFrame({
'customer_id': [1, 2, 3, 4, 5],
'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen', 'Hangzhou']
})
# 模拟订单表
df_order_details = pd.DataFrame({
'order_id': [101, 102, 103, 104, 105, 106],
'customer_id': [1, 2, 3, 1, 5, 99], # 注意:99是一个不存在的客户ID
'product_id': ['A1', 'B2', 'A1', 'C3', 'B2', 'A1'],
'quantity': [2, 1, 5, 3, 2, 4],
'order_date': pd.to_datetime(['2024-01-10', '2024-01-12', '2024-01-15', '2024-01-20', '2024-01-25', '2024-01-28'])
})
# 模拟产品价格表
df_products = pd.DataFrame({
'product_id': ['A1', 'B2', 'C3'],
'product_name': ['Widget', 'Gadget', 'Thingamajig'],
'unit_price': [29.99, 45.50, 12.00]
})
print("客户表:")
print(df_customers)
print("
订单详情表:")
print(df_order_details)
print("
产品表:")
print(df_products)
4.2 数据合并与连接
使用merge函数整合多表数据,处理可能存在的异常(如订单表中的无效客户ID)。
# 1. 连接订单详情与产品表,获取产品名称和单价
df_merged = pd.merge(df_order_details, df_products, on='product_id', how='left')
print("订单与产品合并后:")
print(df_merged)
# 2. 计算每笔订单的金额
df_merged['order_amount'] = df_merged['quantity'] * df_merged['unit_price']
# 3. 连接合并后的订单数据与客户表,使用how='left'保留所有订单,即使客户信息缺失
df_final = pd.merge(df_merged, df_customers, on='customer_id', how='left')
print("
最终合并表 (包含无效客户ID的订单):")
print(df_final)
# 4. 识别并处理无效客户ID的订单(脏数据)
invalid_customer_orders = df_final[df_final['name'].isna()]
valid_customer_orders = df_final.dropna(subset=['name'])
print(f"
发现无效客户ID订单 {len(invalid_customer_orders)} 条:")
print(invalid_customer_orders[['order_id', 'customer_id']])
4.3 聚合分析与数据透视
在数据整合完毕后,进行业务分析,例如计算每个城市的总销售额。
# 按城市统计销售额(只统计有效订单)
city_sales = valid_customer_orders.groupby('city').agg(
total_orders=('order_id', 'nunique'),
total_quantity=('quantity', 'sum'),
total_sales=('order_amount', 'sum')
).reset_index().sort_values('total_sales', ascending=False)
print("
各城市销售统计:")
print(city_sales)
案例五:高效数据筛选与条件查询进阶
5.1 使用query方法进行直观筛选query方法允许使用字符串表达式进行筛选,语法更简洁直观。
# 使用案例四的df_final
# 筛选出订单金额大于100且产品为'Widget'或'Gadget'的订单
high_value_orders = df_final.query('order_amount > 100 and product_name in ["Widget", "Gadget"]')
print("高价值订单(金额>100且产品为Widget或Gadget):")
print(high_value_orders[['order_id', 'product_name', 'quantity', 'order_amount']])
5.2 使用select_dtypes按数据类型筛选列
在处理大型数据框时,快速筛选特定数据类型的列(如所有数值列或对象列)进行批量操作非常有用。
# 筛选出所有数值类型的列
numeric_cols = df_final.select_dtypes(include=['int64', 'float64']).columns
print(f"
数值型列: {list(numeric_cols)}")
# 筛选出所有对象类型(通常是字符串)的列
object_cols = df_final.select_dtypes(include=['object']).columns
print(f"对象型列: {list(object_cols)}")
# 应用:对所有数值列进行描述性统计
print("
数值列描述性统计:")
print(df_final[numeric_cols].describe())
5.3 复杂的多条件组合筛选与赋值
使用loc结合条件进行复杂的数据查询和修改。
# 创建一份副本用于演示
df_demo = df_final.copy()
# 复杂条件:找出北京或上海,购买了Widget产品,且数量大于2的订单
condition = (df_demo['city'].isin(['Beijing', 'Shanghai'])) & \
(df_demo['product_name'] == 'Widget') & \
(df_demo['quantity'] > 2)
target_orders = df_demo.loc[condition]
print("
符合复杂条件(北京/上海,Widget,数量>2)的订单:")
print(target_orders[['order_id', 'city', 'product_name', 'quantity']])
# 使用loc进行条件赋值:为这些符合条件的订单添加一个“优先处理”标记
df_demo.loc[condition, 'priority_flag'] = 'High Priority'
# 为其他订单添加标记
df_demo['priority_flag'] = df_demo['priority_flag'].fillna('Normal')
print(f"
添加优先级标记后,高优先级订单数量: {(df_demo['priority_flag'] == 'High Priority').sum()}")
总结
以上五个案例系统地展示了Pandas在数据分析各环节的核心应用:
- 案例一(RFM模型) 展示了从数据模拟、分组聚合、指标计算到用户分层与可视化的完整流程,是用户行为分析的经典范式。
- 案例二(多维透视) 重点演练了
groupby多级聚合与pivot_table数据透视,适用于制作多维业务报表。 - 案例三(时间序列) 体现了Pandas强大的时间序列处理能力,包括重采样、滚动计算与金融指标分析。
- 案例四(数据整合) 聚焦于多表合并(
merge)的实战,涵盖了数据清洗、连接与异常值处理的关键步骤。 - 案例五(高效筛选) 深入探讨了
query、select_dtypes和基于条件的loc索引等高级筛选技巧,能极大提升数据查询与操作的效率。
通过结合具体的业务场景和数据操作代码,这些案例提供了可直接应用于实际工作的Pandas解决方案模板。掌握这些核心模式,能够应对数据分析中遇到的大部分结构化数据处理任务。
参考来源
- 真香啊,5个小而美的 Pandas 实战案例
- # [特殊字符] Pandas完全学习指南:从入门到实战(4000+字图文教程)
- 4000字详细说明,推荐20个好用到爆的Pandas函数方法
- 【第3章Pandas实战案例与解析 筛选数据】3.158 深度解析:如何用Pandas的select_dtypes()函数高效筛选数据类型
- Pandas教程:近万字讲解在Pandas中如何操作Excel
- Python编程经典案例全解析:从基础语法到实战应用进阶指南
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)