pandas 数据分析实战:从读表到出结论
用一条完整的分析链路串起 pandas 核心能力——数据读取与类型修整、缺失值与异常值处理、分组聚合、表连接、时间序列重采样,最后用透视表回答真实业务问题。

学习信息
pandas 数据分析实战
适合谁
- 有一份销售明细 / 投放明细 / 库存流水,想回答「哪个品类最赚钱」「哪天掉量了」的人
- 会用 Excel 透视表,但数据量一大就卡死的人
- 会 Python 语法,想把分析过程固化成可复用脚本的人
先建立心智模型
pandas 的两大件:Series(一列)和 DataFrame(一张表)。所有操作基本围绕三件事展开:
1. 选:我要哪几行、哪几列 2. 算:按什么维度聚合、算什么指标 3. 拼:多张表怎么关联起来
把这三件事想清楚,剩下的全是查文档。
第一步:把数据读对
import pandas as pd
df = pd.read_excel("sales.xlsx", dtype={"订单号": str})
print(df.shape) # (行数, 列数)
print(df.dtypes) # 每列类型,这里最常出问题
print(df.isna().sum()) # 每列缺失值数量看 dtypes 这一步不能省。日期被读成字符串,后面所有时间分析都会失效;金额被读成 object,聚合时会直接报错或静默出错。
修正常见类型问题:
df["日期"] = pd.to_datetime(df["日期"], errors="coerce")
df["金额"] = pd.to_numeric(df["金额"], errors="coerce")
df["数量"] = pd.to_numeric(df["数量"], errors="coerce").fillna(0).astype("int64")第二步:缺失值与异常值
缺失值没有万能解法,看业务含义决策:
# 关键字段缺失 → 直接删(金额都不知道,这条没法分析)
df = df.dropna(subset=["金额", "日期"])
# 数值型缺失 → 用中位数填充,比均值更抗极端值
df["折扣"] = df["折扣"].fillna(df["折扣"].median())
# 类别型缺失 → 单独成一类,保留「未填写」这个信息本身
df["渠道"] = df["渠道"].fillna("未标注")异常值用分位数而不是拍脑袋:
q1, q3 = df["金额"].quantile([0.25, 0.75])
iqr = q3 - q1
upper = q3 + 1.5 * iqr
outliers = df[df["金额"] > upper]
print(f"疑似异常 {len(outliers)} 条,阈值 {upper:.2f}")先打印出来人工看一眼再决定删还是留。大额订单可能是真实批发单,删掉反而丢掉重要客户。
第三步:分组聚合(最常用)
# 单维度:各品类销售额
by_cat = (
df.groupby("品类", as_index=False)
.agg(销售额=("金额", "sum"), 订单数=("订单号", "nunique"))
.sort_values("销售额", ascending=False)
)
# 双维度:品类 × 渠道
by_cat_chn = df.groupby(["品类", "渠道"], as_index=False)["金额"].sum()
# 顺便算占比
by_cat["占比"] = (by_cat["销售额"] / by_cat["销售额"].sum() * 100).round(2)注意 nunique() 和 count() 的区别:前者数去重后的订单数,后者数行数(含同一订单的多行明细)。算订单量几乎都是前者。
第四步:多表连接
订单表和商品表分开时,用 merge:
products = pd.read_excel("products.xlsx")
merged = df.merge(products, on="商品ID", how="left", validate="many_to_one")
# 检查有没有匹配不上的
print("未匹配行数:", merged["商品名称"].isna().sum())validate="many_to_one" 是个好习惯:如果右表主键有重复,会直接报错提醒你,而不是悄悄把行数翻几倍。
三种 how 的选择:
| 需求 | 参数 | | --- | --- | | 保留左表全部,右表没有就填 NaN | how="left"(最常用) | | 只保留两边都匹配上的 | how="inner" | | 想找「左表有右表没有」的差异 | how="left" + indicator=True |
第五步:时间序列分析
df = df.set_index("日期")
# 按周汇总
weekly = df["金额"].resample("W").sum()
# 7 日移动平均,看趋势而不是看噪声
weekly_ma = weekly.rolling(7).mean()
# 同比环比(对比上一周期)
weekly_mom = weekly.pct_change() * 100W 是周、M 是月、D 是日。做趋势判断时一定要叠加移动平均,单日数据的涨跌大多是噪声。
综合:一张透视表回答业务问题
pv = pd.pivot_table(
df.reset_index(),
index="品类",
columns=df.reset_index()["日期"].dt.to_period("M").astype(str),
values="金额",
aggfunc="sum",
fill_value=0,
margins=True, # 加合计行/列
margins_name="合计",
)
print(pv.round(0))这一张表就能回答:每个品类每月卖了多少、哪个月是高峰、整体合计是多少。直接用 to_excel 输出就是能发给老板的报表。
性能:什么时候会卡
数据量级决定写法:
- 十万行以内:随便写,pandas 秒回
- 百万行以上:读表时加
usecols=只读需要的列、dtype指定类型;必要时分块chunksize - 千万行以上:考虑 polars 或先落库用 SQL 聚合
一个立刻见效的优化:把重复用到的字符串列转成 category 类型,内存能省一大截。
df["品类"] = df["品类"].astype("category")常见问题
SettingWithCopyWarning 警告看不懂? 这是链式赋值导致的。想改子表就显式 .copy(),比如 sub = df[df["金额"] > 100].copy()。
groupby 后索引很乱? 用 as_index=False 或末尾接 .reset_index()。
merge 后行数暴涨? 右表主键重复了,先 products.drop_duplicates(subset=["商品ID"]) 再去连。
下一步
- 可视化:
df.plot()快速看,正式图表用 matplotlib 或 pyecharts - 固定流程:把清洗逻辑封装成函数,每次新数据直接调用
- 交互式看板:Streamlit 几十行就能把分析结果做成网页
常见问题
下载链接失效怎么办?
请优先切换其他网盘渠道,并反馈失效链接。
会员能下载所有资料吗?
页面标注为会员专享的资料支持会员下载,具体以当前页面显示为准。
相关资源
Python 批量处理 Excel 实战(openpyxl + pandas)
面向每天和表格打交道的运营、财务、跨境电商从业者,用 Python 自动完成多表合并、清洗、公式填充、图表输出与定时跑批,把重复的表格操作压缩成一条命令。
用 Codex 做出电商 BI 系统(4 节实操视频课)
电商108将系列的 BI 实操课:用 AI 编程工具 Codex 从零搭一套电商 BI 系统。从把「我想看清生意」翻译成具体需求开始,依次拆解经营指标(销售额、订单数、客单价、毛利率)、建商品分析模型(SKU、类目、销量与动销)、建流量分析模型(曝光、点击、转化、投产)。4 节实操视频,单节 450M 以上,全程带着做。
MCP Server 开发实战:从零构建标准化工具服务
手把手教你开发 MCP Server,实现 tools/list、tools/call、resources/list、resources/read、prompts/list、prompts/get 完整协议,支持 stdio 和 SSE 传输,包含测试、部署、发布最佳实践。
Python 零基础入门教程(2025 完整版)
面向零基础学员的 Python 编程入门教程,覆盖环境搭建、基础语法、流程控制、函数、模块、面向对象、常用库(requests/numpy/pandas),附带 50+ 实战小项目和面试题。
评论建议
欢迎反馈资料质量、链接状态或希望补充的内容,管理员会持续维护。