如果你正在准备数据分析面试、要处理表格类数据,或者想把 Excel 里那套手工操作换成脚本化处理,Pandas 基本是绕不开的第一站。这篇教程按“2 小时速通”的节奏设计,从环境安装到数据清洗、分组聚合、合并关联、格式落地,再到可视化,全部用短代码示例带过一遍。核心原则只有一个:先跑起来,再理解概念。
1. Pandas 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目类型 | Python 数据处理与分析库 |
| 核心数据结构 | Series(一维)、DataFrame(二维) |
| 主要功能 | 数据读取、清洗、筛选、排序、分组、聚合、合并、透视、可视化 |
| 支持数据格式 | CSV、Excel、JSON、Parquet、Feather、SQL、HTML 等 |
| 推荐环境 | Python 3.9 及以上,Pandas 2.x 版本 |
| 硬件要求 | 普通办公电脑即可,无需 GPU |
| 安装方式 | pip / conda 安装 |
| 是否支持 API | 作为 Python 库直接导入使用 |
| 是否支持批量任务 | 支持,可通过循环、函数化批处理多个文件 |
| 适合场景 | 数据清洗、业务报表、面试笔试、数据分析实战、机器学习预处理 |
从表格可以看出来,Pandas 不是重型框架,它更像是数据分析的“基础工具包”。没有独立服务、没有 WebUI、不需要显存,安装后直接在脚本或 Jupyter Notebook 里用。
2. 适用场景与使用边界
Pandas 最常见的落地场景有三类。
第一类是表格数据清洗。Excel 里做的去重、替换、分列、缺失值填充、类型转换,在 Pandas 里几行代码就能完成,而且可以一次处理几百兆甚至几个 G 的数据文件。
第二类是业务分析。按日期、地区、品类做分组汇总,计算同比环比、排名、占比,Pandas 的groupby和pivot_table基本覆盖了 90% 的业务报表需求。
第三类是数据分析和机器学习预处理。Pandas 和 NumPy、Matplotlib、Scikit-learn 配合,完成特征工程、数据切分、标签构造等流程。
使用边界也需要说清楚:
- Pandas 适合单机中等规模数据,处理几千万行级别没问题,但 TB 级数据建议转向 Spark、DuckDB 或 Dask。
- Pandas 不擅长流式计算和实时处理。
- 涉及生产级数据管道时,建议用专门的数据工程框架,Pandas 更适合做分析和探索。
- 数据来源涉及个人信息、商业数据或受版权保护内容时,必须先确认授权和合规要求,学习时使用公开示例数据或自制数据。
3. 环境准备与安装
开始之前,先用命令确认 Python 环境是否正常。
python --version pip --version不同操作系统的 Python 安装方式有差异,但核心要求是 Python 3.9 以上。如果你用的是 PyCharm,可以直接在项目解释器里安装 Pandas,也可以使用终端命令。
Pandas 官方发布版本与 Python 版本有对应关系。一般来说,Python 3.10 可以直接安装 Pandas 2.x 系列,最新安装时 pip 会自动挑选适配的版本。安装命令如下:
pip install pandas如果你需要读 Excel 文件,还需要安装 openpyxl 或 xlrd 引擎:
pip install openpyxl建议再安装 NumPy、Matplotlib,方便后续做数值计算和可视化:
pip install numpy matplotlib安装完成后,在 Python 里验证一下:
import pandas as pd print(pd.__version__)能输出版本号就说明安装成功。如果你用的是 PyCharm,这里有几个常见坑:
- 右下角解释器选择错误:确认当前项目使用的解释器是安装了 Pandas 的那个 Python 环境,而不是系统全局环境。
- 终端执行 pip 和 PyCharm 内部安装不一致:尽量统一使用 PyCharm 的
Python Packages面板,或统一使用终端。 - 网络源慢:国内环境可以临时切换镜像源,但要注意镜像源的选择和安全性。
pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple4. 数据读取与写出
Pandas 的数据读取入口是pd.read_*系列函数,数据写出是to_*系列方法。这里按常用格式逐个演示。
4.1 CSV 文件读写
CSV 是最常见的表格数据格式,业务数据导出、面试题目、竞赛数据集基本都在用。
import pandas as pd df = pd.read_csv("data.csv") print(df.head())写入 CSV 时,如果不想保留默认的行索引,要加index=False:
df.to_csv("output.csv", index=False, encoding="utf-8-sig")utf-8-sig是为了防止 Excel 打开 CSV 乱码。如果字段中包含逗号或换行,Pandas 会自动按 CSV 规范处理引号。
4.2 Excel 文件读写
读取 Excel 需要额外安装 openpyxl:
df = pd.read_excel("报表.xlsx", sheet_name="Sheet1")指定读取某些列:
df = pd.read_excel("报表.xlsx", usecols=["订单号", "金额", "日期"])写出 Excel:
df.to_excel("output.xlsx", sheet_name="结果", index=False)一个 Excel 文件写多个 sheet,需要用到 ExcelWriter:
with pd.ExcelWriter("多表输出.xlsx") as writer: df1.to_excel(writer, sheet_name="汇总", index=False) df2.to_excel(writer, sheet_name="明细", index=False)4.3 Parquet 与 Feather 高性能格式
这是比较进阶的用法,也是很多数据分析岗面试会问的点。
Parquet 和 Feather 都是列式存储格式,优点是压缩率高、读取速度快,非常适合大数据量反复读取的场景。相比 CSV,Parquet 在几百万行级别的数据上读取速度能提升数倍。
# 写出 Parquet df.to_parquet("data.parquet", index=False) # 读取 Parquet df = pd.read_parquet("data.parquet")Feather 格式更轻量,适合 Python 和 R 语言之间交换数据:
df.to_feather("data.feather") df = pd.read_feather("data.feather")这两个格式在 Spark 生态里也很常用。Pandas 处理后的数据可以导出为 Parquet 交给 Spark 读取,实现单机分析和分布式计算的衔接。
4.4 JSON 与数据库读取
# 读取 JSON df = pd.read_json("data.json") # 从数据库读取 import sqlite3 conn = sqlite3.connect("database.db") df = pd.read_sql_query("SELECT * FROM orders", conn)5. DataFrame 基础操作
DataFrame 是 Pandas 最核心的数据结构。你可以把它理解成一个带有列名和行索引的表格。
5.1 创建 DataFrame
import pandas as pd data = { "姓名": ["张三", "李四", "王五", "赵六"], "部门": ["技术部", "市场部", "技术部", "财务部"], "薪资": [12000, 9500, 15000, 8000], "入职日期": ["2023-01-15", "2022-06-01", "2024-03-12", "2021-11-20"] } df = pd.DataFrame(data) print(df)输出效果是:
姓名 部门 薪资 入职日期 0 张三 技术部 12000 2023-01-15 1 李四 市场部 9500 2022-06-01 2 王五 技术部 15000 2024-03-12 3 赵六 财务部 8000 2021-11-205.2 查看基本结构
# 查看前5行 print(df.head()) # 查看列信息 print(df.info()) # 查看数值分布 print(df.describe()) # 查看列名 print(df.columns)info()能看到每列的非空数量、数据类型,describe()会输出计数、均值、标准差、最小值、四分位数、最大值。拿到一份新数据后,先执行这几个方法,基本就能知道数据长什么样。
5.3 选列与选行
# 选择单列,返回 Series print(df["薪资"]) # 选择多列,返回 DataFrame print(df[["姓名", "部门"]]) # 按位置选行,前两行 print(df.iloc[:2]) # 按条件选行 print(df[df["薪资"] > 10000])5.4 新增列与删除列
# 新增一列,计算年薪 df["年薪"] = df["薪资"] * 12 # 新增列,根据条件赋值 df["职级"] = df["薪资"].apply(lambda x: "高级" if x >= 12000 else "普通") # 删除列 df = df.drop(columns=["年薪"])apply是 Pandas 里非常灵活的用法,对每行或每列应用一个函数,适合做复杂字段拆分、标准化等操作。
6. 数据清洗
数据分析工作中,数据清洗往往占掉一半以上的时间。这里整理出最常用的清洗操作。
6.1 缺失值处理
# 查看缺失值情况 print(df.isnull().sum()) # 删除含有缺失值的行 df_clean = df.dropna() # 用固定值填充 df["薪资"] = df["薪资"].fillna(0) # 用均值填充 df["薪资"] = df["薪资"].fillna(df["薪资"].mean()) # 向前填充(用上一条数据填充空值) df["备注"] = df["备注"].fillna(method="ffill")6.2 重复值处理
重点说一个面试高频题:如果指定两列的值均相同,则保留第一条数据。
# 根据姓名和部门两列去重,保留第一条 df_unique = df.drop_duplicates(subset=["姓名", "部门"], keep="first")keep参数有三个选项:
keep="first":保留先出现的行keep="last":保留最后出现的行keep=False:所有重复行都删除
6.3 数据类型转换
数据类型不对是常见问题。比如从 CSV 读入的“日期”列经常是字符串类型。
# 查看数据类型 print(df.dtypes) # 将字符串转为数值 df["薪资"] = pd.to_numeric(df["薪资"], errors="coerce") # 将字符串转为日期 df["入职日期"] = pd.to_datetime(df["入职日期"]) # 将数值转为字符串 df["部门编号"] = df["部门编号"].astype(str) # 自定义转换函数 df["金额_千元"] = df["金额"] / 1000errors="coerce"表示遇到无法转换的值就置为 NaN,而不是报错中断,这个策略在清洗脏数据时非常实用。
6.4 字段拆分与替换
# 拆分列,比如“姓名-部门”拆成两列 df[["姓名", "部门"]] = df["姓名-部门"].str.split("-", expand=True) # 替换值 df["部门"] = df["部门"].replace("技术部", "研发部") # 去除字符串空格 df["姓名"] = df["姓名"].str.strip()6.5 条件筛选与过滤
# 多条件筛选 df_filtered = df[(df["薪资"] > 8000) & (df["部门"] == "技术部")] # 使用 isin df_filtered = df[df["部门"].isin(["技术部", "市场部"])] # 按字符串模糊筛选 df_filtered = df[df["姓名"].str.contains("张")]7. 排序、分组聚合与透视表
7.1 排序
# 按薪资从大到小排序 df_sorted = df.sort_values("薪资", ascending=False) # 多列排序 df_sorted = df.sort_values(["部门", "薪资"], ascending=[True, False])7.2 分组聚合
分组聚合是数据分析的绝对核心。SQL 里的group by在 Pandas 里对应groupby:
# 按部门分组,计算平均薪资 group_result = df.groupby("部门")["薪资"].mean() print(group_result)同时算多个指标:
group_result = df.groupby("部门")["薪资"].agg(["mean", "sum", "max", "min", "count"]) print(group_result)7.3 分组后做多列不同操作
group_result = df.groupby("部门").agg({ "薪资": "mean", "姓名": "count", "业绩": "sum" })agg后面可以传字典,为每一列指定不同的聚合函数。这个写法在面试中非常容易被考察,也是业务分析最常用的写法。
7.4 透视表
透视表相当于 Excel 里的数据透视表功能:
pivot = pd.pivot_table( df, index="部门", columns="季度", values="销售额", aggfunc="sum", fill_value=0 ) print(pivot)7.5 交叉表
交叉表更适合统计频次:
cross = pd.crosstab(df["部门"], df["季度"]) print(cross)8. 数据合并与连接
数据合并通常有两种场景:堆叠和连接。
8.1 纵向堆叠
当多个表字段完全一致时,可以纵向合并:
import pandas as pd df1 = pd.DataFrame({"姓名": ["张三", "李四"], "薪资": [10000, 12000]}) df2 = pd.DataFrame({"姓名": ["王五", "赵六"], "薪资": [9000, 11000]}) df_all = pd.concat([df1, df2], axis=0, ignore_index=True)8.2 横向拼接
字段不同的表按行索引横向拼接:
df_merge = pd.concat([df1, df2], axis=1)8.3 类似 SQL 的 Join
业务分析中最常见的操作是两张表通过某个字段关联:
# 订单表 orders = pd.DataFrame({ "订单号": ["A001", "A002", "A003"], "客户ID": ["C1", "C2", "C3"], "金额": [100, 200, 150] }) # 客户表 customers = pd.DataFrame({ "客户ID": ["C1", "C2", "C4"], "客户名称": ["甲公司", "乙公司", "丁公司"] }) # 左连接,按客户ID关联 result = orders.merge(customers, on="客户ID", how="left") print(result)how参数常用值有:
inner:只保留两边都匹配的行left:保留左边全部行,右边匹配不上为 NaNright:保留右边全部行,左边匹配不上为 NaNouter:保留两边所有行
9. 批量任务处理
Pandas 本身没有专门的批量任务引擎,但通过 Python 的循环和函数化封装,可以轻松实现多文件批量处理。
9.1 批量读取多个 CSV
import pandas as pd import glob file_list = glob.glob("daily_data/*.csv") df_list = [] for file in file_list: temp_df = pd.read_csv(file) df_list.append(temp_df) # 把所有文件纵向合并 all_data = pd.concat(df_list, ignore_index=True) print(all_data.shape)9.2 批量处理并保存
for file in file_list: df = pd.read_csv(file) # 清洗和转换逻辑 df = df.drop_duplicates(subset=["订单号"], keep="first") df["日期"] = pd.to_datetime(df["日期"]) # 保存为 Parquet output_path = "processed/" + file.split("/")[-1].replace(".csv", ".parquet") df.to_parquet(output_path, index=False)实际生产场景中,建议封装成函数,方便后续加日志和失败重试:
from pathlib import Path def process_file(input_path: Path, output_dir: Path): df = pd.read_csv(input_path) df = df.dropna(subset=["金额"]) df["处理时间"] = pd.Timestamp.now() output_path = output_dir / f"{input_path.stem}.parquet" df.to_parquet(output_path, index=False) return output_path for csv_path in Path("daily_data").glob("*.csv"): try: result_path = process_file(csv_path, Path("processed")) print(f"成功: {csv_path} -> {result_path}") except Exception as e: print(f"失败: {csv_path}, 错误: {e}")10. 数据分析与可视化
Pandas 内部自带plot方法,底层基于 Matplotlib。虽然不如专业可视化库精细,但做快速分析足够。
10.1 基础绘图
import matplotlib.pyplot as plt # 让图片在 Jupyter 中直接显示 %matplotlib inline # 按部门统计平均薪资,并绘制柱状图 df.groupby("部门")["薪资"].mean().plot(kind="bar") plt.title("各部门平均薪资") plt.ylabel("平均薪资") plt.xticks(rotation=45) plt.show()10.2 折线图
处理时间序列数据时,折线图最直观:
# 按日期汇总销售额,再画折线图 df["日期"] = pd.to_datetime(df["日期"]) df.set_index("日期").resample("D")["销售额"].sum().plot(kind="line") plt.show()resample("D")是按天重采样,换成"W"按周、"M"按月。这是时序分析中最高频的操作。
10.3 直方图与箱线图
# 薪资分布直方图 df["薪资"].hist(bins=20) # 各部门薪资分布箱线图 df.boxplot(column="薪资", by="部门") plt.show()可视化只是辅助验证手段,重点是观察数据分布和异常值,不要为了画图而画图。
11. 资源占用与性能观察
Pandas 在普通办公电脑上就能跑,但数据量大时仍然要注意资源占用。
11.1 观察内存占用
# 查看 DataFrame 整体内存占用 print(df.memory_usage(deep=True).sum() / 1024 / 1024, "MB")一条简单的内存检查可以帮你判断当前数据是否适合用 Pandas 处理。单文件超过 1GB 时,建议先抽样测试,或者使用read_csv的nrows参数只读一部分:
df_sample = pd.read_csv("big_file.csv", nrows=10000)11.2 降低内存的方法
- 优先筛选列,不用的列直接不读:
df = pd.read_csv("big_file.csv", usecols=["订单号", "金额", "日期"])- 使用
category类型压缩重复值高的列:
df["部门"] = df["部门"].astype("category")- 将数值型降位:
float64转为float32,int64转为int32。
11.3 性能观察技巧
处理几千行时,Pandas 几乎是瞬时完成;处理几百万行时,建议关注:
- 操作耗时:使用
time模块或 Jupyter%%time魔法命令。 - 内存变化:使用系统资源监视器,或结合
memory_usage分阶段打印。 - I/O 耗时:CSV 读取远慢于 Parquet 和 Feather,高频读取场景优先用列式格式。
12. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
pip install pandas安装失败 | pip 版本过低,或 Python 版本过旧 | 执行python --version和pip --version | 升级 pip,或升级 Python 到 3.9+ |
| 安装速度慢 | 默认 PyPI 源网络不稳定 | 检查网络连接 | 更换镜像源或重试 |
ModuleNotFoundError: No module named 'pandas' | PyCharm 使用了解释器错误 | 查看 PyCharm 右下角解释器 | 切换解释器,或重新安装 Pandas |
| 读取 Excel 报错 | 缺少 openpyxl 或 xlrd 引擎 | 查看报错信息 | pip install openpyxl |
sort_values后中文排序不对 | 未指定排序规则 | 观察排序结果 | 使用key参数,或按转换后的拼音列排序 |
| 去重后行数异常 | subset参数未指定 | 检查代码 | 指定subset列范围 |
| CSV 写入后 Excel 中文乱码 | 编码不对 | 用文本编辑器打开验证 | 使用encoding="utf-8-sig" |
| 日期列处理报错 | 数据中混有非日期值 | 打印该列唯一值 | pd.to_datetime(..., errors="coerce") |
| 数据量很大时内存爆掉 | 一次性读取全部数据 | 检查memory_usage | 分块读取或改用 Parquet 格式 |
concat后索引重复 | 未重置索引 | 查看结果 | 加ignore_index=True |
| 批量处理中某个文件失败 | 单个文件格式异常 | 打日志定位文件 | 使用try-except捕获并跳过 |
| 可视化中文乱码 | Matplotlib 字体配置问题 | 查看绘图结果 | 配置中文字体,如plt.rcParams["font.sans-serif"] = ["SimHei"] |
13. 最佳实践与使用建议
第一,第一次拿到数据时,先执行head()、info()、describe(),把数据的列名、类型、缺失情况、数值范围摸清楚,再开始处理。盲目写清洗代码容易踩坑。
第二,清理脏数据是一个反复迭代的过程,建议把清洗流程封装成独立函数,方便每次读取新文件后直接复用。不要每次手工复制代码。
第三,重要数据处理前先做备份,处理流程加上中间结果打印,比如处理前后行数对比、缺失值数量对比。这样能及时发现逻辑错误。
第四,数据处理脚本要养成加日志的习惯。批量任务中,每条文件处理成功或失败都记录下来,失败时保留原始文件,方便重新处理。
import logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" ) def process_file(file_path): try: df = pd.read_csv(file_path) # 处理逻辑 df.to_parquet("output.parquet") logging.info(f"文件处理成功: {file_path}") except Exception as e: logging.error(f"文件处理失败: {file_path}, 错误: {e}")第五,涉及商务数据和个人信息的数据分析项目,要在授权和合规前提下进行。学习阶段尽量使用公开数据集或自己构造的数据,避免直接使用真实业务数据截图和导出文件。
第六,面试和笔试方面,Pandas 高频考点集中在groupby、merge、pivot_table、drop_duplicates、to_datetime、fillna、apply这几个方法,建议每个方法都手写一遍完整示例,而不是只看不练。
第七,学习路径上,先掌握 Series 和 DataFrame 基础操作,再学数据清洗和筛选,然后学分组聚合和合并,最后学批量处理和可视化。按照“读数据 -> 清洗 -> 分析 -> 输出”的流程做三个完整案例,基本上就能覆盖日常工作核心场景。
14. 总结与下一步
Pandas 是数据分析工具链中最基础、最实用的一环。它的优点在于学习曲线平缓、社区资料充足、与 Excel 操作可以对应理解。2 小时速通的核心思路是优先掌握高频操作,不要一开始纠结于底层实现,而是围绕“读写数据 -> 清洗数据 -> 分组聚合 -> 合并关联 -> 结果输出”这条主线建立完整的处理流程。
最容易踩的坑集中在三个方面:环境配置错误导致无法导入、数据清洗时忽略缺失值和类型转换、批量任务没有日志导致难以排查。建议你按照本文的代码示例在本地 Python 环境或 Jupyter Notebook 里逐段运行,并准备一份包含日期、金额、部门、客户 ID 的模拟数据,把去重、分组、透视表、合并全部跑一遍。
下一步可以继续扩展的方向:学会用 Pandas 与 NumPy 配合做特征工程,再用 Matplotlib 或 Seaborn 做探索性分析,然后过渡到用 Sklearn 做机器学习建模。Pandas 不是终点,它是通往更深层数据分析的起点。建议把本文收藏备用,编写代码时遇到格式转换、去重、合并、聚合的问题,可以直接回来查示例。