
1. 为什么要学 Pandas数据分析的起点在做数据分析之前很多人的第一反应是打开 Excel。Excel 确实足够直观但当数据量达到几十万行、几百万行或者需要重复执行清洗、汇总、关联操作时Excel 就会变得力不从心。这时候Pandas 就是 Python 生态里最核心的数据分析利器。Pandas 是一个基于 Python 的开源数据分析库名字来源于“Panel Data”面板数据。它提供了两类核心数据结构Series一维和DataFrame二维。借助这两个结构你可以完成数据读取、清洗、转换、聚合、可视化等一系列操作。在实际开发中Pandas 常见的应用场景包括数据清洗处理缺失值、重复值、异常值。数据转换类型转换、字段抽取、分箱、归一化。数据聚合分组统计、透视表、多表关联。数据输出把处理结果导出为 Excel、CSV、数据库表。与机器学习联动为 sklearn、XGBoost 等模型准备训练数据。本文会围绕一套“由浅入深”的学习路径先理解核心数据结构再掌握数据读写接着完成数据清洗和数据分析实战案例最后补充常见问题和工程建议。文章中的代码均基于 Python 3 Pandas 编写读者可以直接复制运行。2. Pandas 环境准备与安装在开始写代码之前先确认环境中已经安装了 Pandas。2.1 检查 Python 版本Pandas 对 Python 版本有一定要求。写教程时当前稳定版本通常支持 Python 3.9 及以上。如果你使用的是 Python 3.10一般可以直接安装最新版 Pandas如果使用更高版本或更老版本建议先查看官方安装文档。打开终端Windows 为 CMD 或 PowerShellmacOS / Linux 为 Terminal执行python --version如果提示python不是内部或外部命令可以尝试python3 --version2.2 安装 Pandas使用 pip 安装pip install pandas如果你的环境同时存在多个 Python 版本建议使用虚拟环境避免包冲突。例如使用 venvpython -m venv .venv .venv\Scripts\activate # Windows source .venv/bin/activate # macOS / Linux pip install pandas安装完成后验证版本import pandas as pd print(pd.__version__)看到类似2.1.4的输出说明安装成功。2.3 搭配工具推荐Pandas 只是一个库还需要一个运行环境。常用选择Jupyter Notebook适合交互式分析数据展示直观。PyCharm适合写完整脚本和工程化分析代码。VS Code Python 插件轻量、灵活。本文示例在 Jupyter Notebook 和 PyCharm 中均可运行关键是要把示例代码按顺序复制到同一个.py文件或 Notebook Cell 中。3. 核心数据结构Series 和 DataFrame学习 Pandas第一步不是背 API而是弄清楚两个核心对象——Series和DataFrame。3.1 Series带索引的一维数组Series可以理解为“带标签的一维数组”。它由两部分组成数据部分任意类型整数、浮点数、字符串、对象。索引部分每个数据的标签默认是0, 1, 2, ...。创建一个最简单的 Seriesimport pandas as pd s pd.Series([10, 20, 30, 40]) print(s)输出0 10 1 20 2 30 3 40 dtype: int64你也可以显式指定索引s pd.Series([10, 20, 30], index[a, b, c]) print(s)输出a 10 b 20 c 30 dtype: int64这里的索引相当于“行名”在数据分析中很有用比如按月份、按城市作为索引。3.2 DataFrame带行列标签的二维表格DataFrame是 Pandas 最常用的数据结构可以理解成一张 Excel 表或一张数据库表。它由行索引index和列名columns组成。创建一个 DataFrameimport pandas as pd df pd.DataFrame({ 姓名: [张三, 李四, 王五], 部门: [技术部, 产品部, 运营部], 薪资: [15000, 13000, 12000] }) print(df)输出姓名 部门 薪资 0 张三 技术部 15000 1 李四 产品部 13000 2 王五 运营部 12000创建后可以查看一些常用属性print(df.shape) # 几行几列 print(df.columns) # 列名 print(df.index) # 行索引 print(df.dtypes) # 每一列的数据类型 print(df.info()) # 数据概览df.info()的输出会显示行数、列数、非空值数量和每列类型这对于检查数据完整性非常有用。3.3 从列表、字典、NumPy 数组创建除了字典方式还可以从列表嵌套创建df2 pd.DataFrame([ [张三, 技术部, 15000], [李四, 产品部, 13000] ], columns[姓名, 部门, 薪资])从 NumPy 数组创建import numpy as np arr np.array([[1, 2], [3, 4]]) df3 pd.DataFrame(arr, columns[A, B])理解这两个结构之后就可以开始做“正事”了——读取数据。4. 数据读取与写入CSV、Excel、Parquet数据分析的第一步通常是把外部数据载入到 Pandas 中。常用的数据源包括 CSV、Excel、Parquet、Feather 和数据库。4.1 读取 CSV 文件import pandas as pd df pd.read_csv(sales_data.csv) print(df.head())head()默认显示前 5 行用于快速预览数据。如果 CSV 文件没有列名可以指定headerNone并手动设置列名df pd.read_csv(sales_data.csv, headerNone, names[日期, 销售额, 订单数])如果文件编码不是 UTF-8会出现乱码。比如中文 CSV 经常使用gbk编码可以这样读取df pd.read_csv(sales_data.csv, encodinggbk)4.2 读取 Excel 文件读取 Excel 需要额外的openpyxl或xlrd库先安装pip install openpyxl然后读取df pd.read_excel(sales_data.xlsx, sheet_nameSheet1)如果 Excel 里有多个 Sheet可以用sheet_nameNone读取全部返回一个字典key 是 Sheet 名value 是对应的 DataFrame。4.3 读取 Parquet 和 Feather在大数据场景下Parquet 和 Feather 是两种高效的列式存储格式。很多从 Spark、Hive 同步过来的数据会直接落地为 Parquet用 Pandas 读取非常方便。df pd.read_parquet(sales_data.parquet)读取 Featherdf pd.read_feather(sales_data.feather)需要提醒的是read_parquet依赖pyarrow或fastparquet。安装命令pip install pyarrow写回文件时可以这样# 导出为 CSV df.to_csv(output_data.csv, indexFalse) # 导出为 Excel df.to_excel(output_data.xlsx, indexFalse) # 导出为 Parquet df.to_parquet(output_data.parquet) # 导出为 Feather df.to_feather(output_data.feather)indexFalse的意思是不要把行索引导出为一列通常更符合分析需求。4.4 读取数据库表如果数据在 MySQL 或 PostgreSQL 中可以用read_sqlimport pandas as pd from sqlalchemy import create_engine engine create_engine(mysqlpymysql://用户名:密码localhost:3306/数据库名) df pd.read_sql(SELECT * FROM sales_table, conengine)读取数据库前务必确认权限和网络是否允许生产环境不要随便用高权限账号执行操作。5. 数据清洗实战缺失值、重复值、类型转换真实场景里的数据很少是干净的数据清洗是 Pandas 学习中最耗时间的部分。下面结合一个业务示例演示。先构造一份“员工销售数据”故意加入缺失值和重复值import pandas as pd import numpy as np data { 员工ID: [E001, E002, E003, E004, E005, E001], 姓名: [张伟, 李娜, 王强, 赵敏, 刘洋, 张伟], 部门: [销售一部, 销售二部, 销售一部, np.nan, 销售三部, 销售一部], 销售额: [12000, 9800, None, 15000, 8800, 12000], 日期: [2024-01-05, 2024-01-06, 2024-01-07, 2024-01-08, 2024-01-09, 2024-01-05] } df pd.DataFrame(data) print(df)输出员工ID 姓名 部门 销售额 日期 0 E001 张伟 销售一部 12000.0 2024-01-05 1 E002 李娜 销售二部 9800.0 2024-01-06 2 E003 王强 销售一部 NaN 2024-01-07 3 E004 赵敏 NaN 15000.0 2024-01-08 4 E005 刘洋 销售三部 8800.0 2024-01-09 5 E001 张伟 销售一部 12000.0 2024-01-05可以看到这份数据既有缺失值NaN又有完全重复的行第 0 行和第 5 行日期列也是字符串类型而不是时间类型。5.1 检查缺失值print(df.isnull()) print(df.isnull().sum())isnull()会返回一个同形状的布尔 DataFramesum()按列统计缺失值数量。5.2 处理缺失值处理缺失值有两种思路删除和填充。删除包含缺失值的行df_drop df.dropna() print(df_drop)填充缺失值比如销售额缺失用该列均值填充df[销售额] df[销售额].fillna(df[销售额].mean())部门缺失用“未知部门”填充df[部门] df[部门].fillna(未知部门)注意fillna返回的是新 DataFrame不会原地修改因此需要重新赋值或者设置inplaceTrue。不过现在更推荐直接赋值的方式可读性更好。5.3 删除重复值根据所有列判断重复行df df.drop_duplicates()如果只想根据“员工ID”判断重复保留第一条df df.drop_duplicates(subset[员工ID], keepfirst)热搜词里提到“如果指定两列的值均相同则取第一条数据”写法就是df df.drop_duplicates(subset[员工ID, 姓名], keepfirst)keepfirst表示保留重复组中的第一条keeplast保留最后一条keepFalse删除所有重复行。5.4 数据类型转换Pandas 中常见的数据类型包括int64、float64、object、datetime64等。处理日期字符串时需要转为时间类型df[日期] pd.to_datetime(df[日期]) print(df.dtypes)把销售额从浮点型转成整数型df[销售额] df[销售额].astype(int)数据清洗后再看一眼数据print(df)输出员工ID 姓名 部门 销售额 日期 0 E001 张伟 销售一部 12000 2024-01-05 1 E002 李娜 销售二部 9800 2024-01-06 3 E004 赵敏 未知部门 15000 2024-01-08 4 E005 刘洋 销售三部 8800 2024-01-09这样就得到一个相对干净、可继续分析的数据集。6. 数据分析实战筛选、排序、分组聚合数据清洗完成后就进入真正的分析阶段。这里用一个更完整的数据集模拟“某公司销售订单明细”。import pandas as pd sales_df pd.DataFrame({ 订单号: [A001, A002, A003, A004, A005, A006], 地区: [华东, 华北, 华东, 华南, 华北, 华南], 品类: [手机, 电脑, 手机, 平板, 手机, 电脑], 销售额: [5000, 8000, 4500, 6000, 5200, 9200], 利润: [800, 1200, 600, 900, 700, 1500] }) print(sales_df)6.1 按条件筛选数据筛选销售额大于 5000 的记录high_sales sales_df[sales_df[销售额] 5000] print(high_sales)多条件筛选用表示“且”用|表示“或”。注意每个条件都要加括号# 华东地区且销售额大于5000 result sales_df[(sales_df[地区] 华东) (sales_df[销售额] 5000)] print(result)6.2 排序按销售额降序排序sorted_df sales_df.sort_values(销售额, ascendingFalse) print(sorted_df)多列排序sorted_df sales_df.sort_values([地区, 销售额], ascending[True, False])6.3 分组聚合分组聚合是 Pandas 最核心的能力之一。比如统计每个地区销售额总和grouped sales_df.groupby(地区)[销售额].sum() print(grouped)输出地区 华东 9500 华北 13200 华南 15200 Name: 销售额, dtype: int64也可以一次统计多个指标result sales_df.groupby(地区).agg({ 销售额: [sum, mean, count], 利润: sum }) print(result)这里的agg可以传入字典key 是列名value 是要执行的聚合函数。还可以用列表result sales_df.groupby(地区)[销售额].agg([sum, mean, max, min])6.4 多列分组按“地区 品类”两个维度统计result sales_df.groupby([地区, 品类])[销售额].sum().reset_index() print(result)reset_index()的作用是把分组后的索引重新变成普通列方便后续导出或继续处理。6.5 透视表透视表能更直观地展示二维汇总结果pivot_df pd.pivot_table( sales_df, values销售额, index地区, columns品类, aggfuncsum, fill_value0 ) print(pivot_df)输出品类 平板 手机 电脑 地区 华东 0 9500 0 华北 0 5200 8000 华南 6000 0 9200这就类似于 Excel 透视表在分析报表中非常常见。7. 数据可视化用 Pandas Matplotlib 快速出图数据分析的最后一环往往是可视化。Pandas 本身不提供绘图能力但可以很方便地调用 Matplotlib。7.1 安装和导入pip install matplotlib在代码中启用 Matplotlib 并设置中文显示避免中文乱码import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # Windows 常用黑体 plt.rcParams[axes.unicode_minus] False # 解决负号显示问题macOS 或 Linux 可以换成[Arial Unicode MS]或系统支持的中文字体。7.2 柱状图按地区汇总销售额后画柱状图sales_by_region sales_df.groupby(地区)[销售额].sum() sales_by_region.plot(kindbar, title各地区销售额对比) plt.ylabel(销售额) plt.show()7.3 折线图如果有时间序列数据折线图更适合time_df pd.DataFrame({ 月份: [2024-01, 2024-02, 2024-03, 2024-04], 销售额: [2000, 3500, 2800, 4200] }) time_df.plot(x月份, y销售额, kindline, markero, title月度销售额趋势) plt.ylabel(销售额) plt.show()7.4 饼图展示品类占比sales_by_category sales_df.groupby(品类)[销售额].sum() sales_by_category.plot(kindpie, autopct%1.1f%%, title品类销售额占比) plt.ylabel() plt.show()可视化的核心目的是让数据结论一目了然。实际项目中不需要花哨清晰、准确更重要。8. 常见问题与排查思路8.1 常见报错速查表下面列出新手使用 Pandas 时最常遇到的几类问题以及排查思路。问题现象常见原因解决思路ModuleNotFoundError: No module named pandas尚未安装或装到了另一个 Python 环境确认当前解释器执行pip install pandas读取 CSV 中文乱码编码格式不对指定encodinggbk或encodingutf-8列名有空格或中文代码报错用df.列名访问有局限优先使用df[列名]修改列后数据未生效忘记重新赋值Pandas 大多数操作返回新对象需df df.dropna()KeyError: 列名列名拼写错误或不存在用df.columns查看实际列名groupby 后想转回普通表索引层级复杂使用.reset_index()安装 pandas 报错版本冲突Python 与 Pandas 版本不匹配查阅官方文档升级 Python 或指定兼容版本8.2 关于 Python 3.10 与 Pandas 的版本搭配如果你的 Python 是 3.10最新的 Pandas 稳定版一般都支持。比较稳妥的方式是pip install --upgrade pandas如果安装后导入报错比如缺少依赖库可以先安装numpy、python-dateutil、pytz等基础依赖再重装 Pandas。8.3 处理大文件时内存不足如果数据量很大比如几个 GB 的 CSV推荐分块读取chunk_iter pd.read_csv(big_file.csv, chunksize10000) result_parts [] for chunk in chunk_iter: # 先做清洗 chunk chunk.dropna() # 再做聚合 result_parts.append(chunk.groupby(类目)[销售额].sum()) final_result pd.concat(result_parts).groupby(level0).sum()分块读取的核心思路是每次只处理 10000 行减少内存占用最后合并结果。9. 最佳实践与工程建议写了几年代码之后你会发现 Pandas 入门不难但要把代码写得稳定、可维护、可复用还是需要一些工程经验的积累。下面分享几组实用建议。9.1 用自定义函数组织数据处理流程直接写一大段脚本后期维护很痛苦。建议把每个环节封装成函数def load_data(file_path): return pd.read_csv(file_path) def clean_data(df): df df.drop_duplicates(subset[订单号]) df df.dropna(subset[销售额]) df[日期] pd.to_datetime(df[日期]) return df def analyze_data(df): return df.groupby(地区)[销售额].sum().reset_index() def main(): df load_data(sales.csv) df clean_data(df) result analyze_data(df) result.to_csv(sales_result.csv, indexFalse) if __name__ __main__: main()这样每一步都可以单独测试也方便复用。9.2 尽量少用inplaceTrueinplaceTrue会原地修改 DataFrame虽然省内存但在管道式处理和调试时容易产生副作用。推荐写法是“生成新对象并重新赋值”逻辑更清晰也便于链式操作。9.3 注意链式赋值的坑有些新手会这样写df[df[销售额] 5000][标记] 高这被称为“链式赋值”可能只修改了副本而不是原表甚至会触发SettingWithCopyWarning。正确做法是df.loc[df[销售额] 5000, 标记] 高loc是先按条件定位再修改列稳定又明确。9.4 数据备份与操作安全涉及修改原始数据时尤其是从数据库临时表或生产环境取数据建议先做好备份df_backup df.copy()这样即使清洗逻辑写错了也可以快速回退不需要重新读一遍数据。9.5 用nunique、value_counts辅助快速探查数据分析前先摸清数据基本情况# 每个城市的数量分布 print(df[城市].value_counts()) # 每个员工覆盖了多少个城市 print(df.groupby(员工)[城市].nunique())这些指令能帮你快速判断数据完整性和业务规则比直接跑统计模型更有价值。10. 实战扩展金融风控场景中的 Pandas 应用数据分析本身是方法落地到具体领域才有生命力。这里以一个金融风控场景为例演示 Pandas 的完整用法也能帮你巩固前面所有内容。假设有一份“用户交易记录”数据字段包括用户ID、交易金额、交易时间、是否命中风控规则。import pandas as pd import numpy as np trade_data pd.DataFrame({ 用户ID: [U001, U002, U003, U001, U004, U002], 交易金额: [2000, 8500, 300, 15000, 5000, None], 交易时间: [2024-03-01 10:00:00, 2024-03-01 10:05:00, 2024-03-01 10:10:00, 2024-03-02 09:30:00, 2024-03-02 09:45:00, 2024-03-02 10:00:00], 命中规则: [否, 是, 否, 是, 否, 是] })第一步清洗。把时间转为 datetime删除空交易金额。trade_data[交易时间] pd.to_datetime(trade_data[交易时间]) trade_data trade_data.dropna(subset[交易金额])第二步按用户聚合。统计每个用户的交易次数、总金额、最大单笔金额、平均金额。user_stats trade_data.groupby(用户ID).agg({ 交易金额: [count, sum, max, mean] }).round(2) print(user_stats)第三步找出可疑用户。比如单日交易次数过多或者命中风控规则的占比过高。这里简单演示“交易总金额大于 10000 的用户”user_total trade_data.groupby(用户ID)[交易金额].sum() high_risk_users user_total[user_total 10000] print(high_risk_users)输出用户ID U001 17000.0 Name: 交易金额, dtype: float64这个案例虽然简单但完整覆盖了“读取、清洗、分组聚合、筛选”四条主线。金融风控场景中还需要结合时间窗口分析、落库、监控预警等这些都可以基于同样的 Pandas 功底逐步扩展。11. 结束语Pandas 这条路该怎么继续走Pandas 是一座很好的桥它能帮你从 Excel 表格思维过渡到编程化数据分析思维。通过本文你应该已经掌握Series 和 DataFrame 两个核心数据结构CSV、Excel、Parquet、Feather 等文件的读写方式缺失值、重复值、类型转换等数据清洗操作筛选、排序、分组聚合、透视表等分析手段配合 Matplotlib 输出可视化图表的基本流程常见报错的排查思路和工程化的写法建议。下一步建议按这个顺序继续深入先自己找一份真实数据集完整跑一遍清洗和分析流程然后学习apply自定义函数解决更复杂的业务逻辑接着了解merge和concat掌握多张表关联最后可以接触 Spark 或 Dask让 Pandas 分析能力延伸到更大的数据规模。如果本文对你有帮助可以收藏备用遇到具体问题欢迎在评论区留言交流。