Python 玩转 Excel 案例【第 8 期】
案例说明
原始数据表: 一季度销售数据(共20条记录,展示前5条)
┌──────────┬────────────┬──────────┬──────────┬────────────┬──────────────┐
│ 销售年份 │ 成交日期 │ 订单编号 │ 客户代码 │ 是否VIP客户 │ 是否团购订单 │
├──────────┼────────────┼──────────┼──────────┼────────────┼──────────────┤
│ 2024 │ 2026-03-15 │ ORD001 │ C001 │ 是 │ 否 │
├──────────┼────────────┼──────────┼──────────┼────────────┼──────────────┤
│ 2024 │ 2026-03-16 │ ORD002 │ C002 │ 否 │ 是 │
├──────────┼────────────┼──────────┼──────────┼────────────┼──────────────┤
│ 2024 │ 2026-03-17 │ ORD003 │ C003 │ 是 │ 否 │
├──────────┼────────────┼──────────┼──────────┼────────────┼──────────────┤
│ 2024 │ 2026-03-18 │ ORD004 │ C004 │ 否 │ 否 │
├──────────┼────────────┼──────────┼──────────┼────────────┼──────────────┤
│ 2024 │ 2026-03-19 │ ORD005 │ C005 │ 是 │ 是 │
└──────────┴────────────┴──────────┴──────────┴────────────┴──────────────┘
*注:完整表格共20行数据,此处仅展示前5行作为示例*
目标任务:
从上述Excel表中,筛选出同时满足以下两个条件的记录:
条件一:年份范围
- • 只保留
销售年份 为 2023年 或 2024年 的数据
条件二:时间范围
- • 例如:现在是2026年3月,则只保留3月份的记录
完整代码
import pandas as pd
from datetime import datetime
# 定义需要读取的字段
required_columns = ['销售年份', '成交日期', '订单编号', '客户代码',
'是否VIP客户', '是否团购订单']
# 读取Excel文件
sales_data = pd.read_excel(
'chapter-8.xlsx',
sheet_name='一季度销售数据',
engine='openpyxl',
header=0,
usecols=required_columns
)
print(f"读取到的原始记录数: {len(sales_data)}条")
# 筛选特定年份的数据
if '销售年份' in sales_data.columns:
sales_data = sales_data[sales_data['销售年份'].astype(int).isin([2023, 2024])]
print(f"年份筛选后剩余: {len(sales_data)}条")
# 筛选成交日期为当月的数据
sales_data['成交日期'] = pd.to_datetime(sales_data['成交日期'], errors='coerce')
# 获取当前年份和月份
now = datetime.now()
current_year = now.year
current_month = now.month
month_filter = (sales_data['成交日期'].dt.year == current_year) & \
(sales_data['成交日期'].dt.month == current_month)
sales_data = sales_data[month_filter]
print(sales_data.head())
第一步:导入所需库
import pandas as pd
from datetime import datetime
代码解释:
- •
import pandas as pd:导入 pandas 库,它是 Python 数据分析的核心库,可以处理各种数据格式 - •
from datetime import datetime:从 datetime 模块导入 datetime 类,用于获取当前时间
💡 特别说明:engine='openpyxl' 是指定 pandas 用 openpyxl 引擎读取 .xlsx 文件,只需安装无需导入,pandas 会在内部自动调用。
第二步:定义需要读取的字段
required_columns = ['销售年份', '成交日期', '订单编号', '客户代码',
'是否VIP客户', '是否团购订单']
代码解释:
- • 创建一个列表
required_columns,定义需要从Excel中读取的列名 - • 这样做可以只读取需要的列,提高读取效率,减少内存占用
第三步:读取 Excel 文件
sales_data = pd.read_excel(
'chapter-8.xlsx',
sheet_name='一季度销售数据',
engine='openpyxl',
header=0,
usecols=required_columns
)
参数详解:
- •
'chapter-8.xlsx':Excel 文件名 - •
sheet_name='一季度销售数据':指定要读取的工作表名称 - •
engine='openpyxl':指定读取引擎,处理 .xlsx 文件必须使用 openpyxl - •
header=0:指定第 0 行作为列名(数据表的第一行) - •
usecols=required_columns:只读取我们定义的字段
执行结果:
print(f"读取到的原始记录数: {len(sales_data)}条")
读取到的原始记录数: 20条
💡 小贴士:如果Excel文件很大,建议只读取需要的列,可以大大加快读取速度!
第四步:筛选特定年份数据
if '销售年份' in sales_data.columns:
sales_data = sales_data[sales_data['销售年份'].astype(int).isin([2023, 2024])]
print(f"年份筛选后剩余: {len(sales_data)}条")
代码详解:
- •
if '销售年份' in sales_data.columns:检查年份列是否存在,避免程序报错 - •
sales_data['销售年份'].astype(int):将年份列转换为整数类型 - •
.isin([2023, 2024]):判断年份是否在 [2023, 2024] 列表中 - • 最外层
sales_data[...]:用布尔索引筛选出符合条件的行
执行结果:
年份筛选后剩余: 18条
💡 小贴士:为什么不用 == 而用 isin()?因为 isin() 可以一次性筛选多个值,代码更简洁!
第五步:处理日期数据
sales_data['成交日期'] = pd.to_datetime(sales_data['成交日期'], errors='coerce')
代码详解:
- •
pd.to_datetime():将成交日期列转换为 datetime 类型 - •
errors='coerce':遇到无效日期时设置为 NaT(Not a Time),避免程序中断
第六步:获取当前时间
now = datetime.now()
current_year = now.year
current_month = now.month
print(f"当前年份: {current_year}")
print(f"当前月份: {current_month}")
执行结果(假设当前是2026年3月):
当前年份: 2026
当前月份: 3
第七步:筛选当月数据
month_filter = (sales_data['成交日期'].dt.year == current_year) & \
(sales_data['成交日期'].dt.month == current_month)
sales_data = sales_data[month_filter]
print(f"当月数据筛选后剩余: {len(sales_data)}条")
print("\n最终筛选结果:")
print(sales_data)
代码详解:
⚠️ 特别注意:运算符优先级问题
# ❌ 错误写法(缺少括号):
month_filter = (sales_data['成交日期'].dt.year == current_year & \
sales_data['成交日期'].dt.month == current_month)
# ✅ 正确写法(每个条件用括号包裹):
month_filter = (sales_data['成交日期'].dt.year == current_year) & \
(sales_data['成交日期'].dt.month == current_month)
为什么?
- • 不加括号时,
current_year & sales_data['成交日期'].dt.month 会先被计算
执行结果(2026年3月的数据):
当月数据筛选后剩余: 11条
最终筛选结果:
销售年份 成交日期 订单编号 客户代码 是否VIP客户 是否团购订单
0 2024 2026-03-15 ORD001 C001 是 否
1 2024 2026-03-16 ORD002 C002 否 是
2 2023 2026-03-17 ORD003 C003 是 否
3 2024 2026-03-18 ORD004 C004 否 否
4 2023 2026-03-19 ORD005 C005 是 是
📌 本期核心知识点
📍 知识点 1:Excel文件读取
pd.read_excel(..., engine='openpyxl') 用于读取 .xlsx 文件,只需安装无需导入 openpyxl,未安装会提示缺失依赖。
📍 知识点 2:日期格式转换
pd.to_datetime() 将Excel中的日期字符串转换为真正的日期类型,加上 errors='coerce' 可以防止脏数据导致程序崩溃。
📍 知识点 3:当前时间获取
datetime.now().year 和 .month 用于获取当前系统时间的年份和月份,实现动态筛选当月数据。
📍 知识点 4:年份批量筛选
.isin([2023, 2024]) 可以一次性筛选多个年份,比用多个 == 条件更简洁高效。
📍 知识点 5:日期维度提取
.dt.year 和 .dt.month 可以从日期列中提取年份和月份,前提是必须先经过 pd.to_datetime() 转换。
📍 知识点 6:布尔索引筛选
df[条件] 这种写法叫布尔索引,会返回所有满足条件的行,是pandas中最常用的数据筛选方式。
📍 知识点 7:运算符优先级
用 & 连接多个条件时,每个条件必须用括号包裹,即写成 (条件1) & (条件2),否则会因优先级问题得到错误结果。
本案例核心流程
① 读取Excel → ② 转换日期 → ③ 获取当前时间 → ④ 筛选年份 → ⑤ 筛选月份
对应代码:
# ① 读取
df = pd.read_excel('file.xlsx', engine='openpyxl')
# ② 转换
df['日期'] = pd.to_datetime(df['日期'], errors='coerce')
# ③ 获取当前时间
now = datetime.now()
# ④ 筛选年份
df = df[df['年份'].isin([2023, 2024])]
# ⑤ 筛选月份
df = df[(df['日期'].dt.year == now.year) & (df['日期'].dt.month == now.month)]
📦 资源获取提示
关注「码农自习室」,后台回复关键词 PythonExcel案例,即可获取本文完整代码及配套练习数据集,一起动手掌握高效数据操作的核心技巧!
❤️ 支持我们
如果本文对你有帮助,欢迎点赞 + 关注 + 点亮小红心,你的支持就是我们持续创作的最大动力~