ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Pandas入门指南:从数据清洗到分组聚合的完整实战

Pandas入门指南:从数据清洗到分组聚合的完整实战 1. 数据分析入门为什么绕不开 Pandas很多刚接触数据分析的人都会遇到同一个场景手里拿到一份 Excel 表几千行、几十列老板让你统计“每个城市销售额排名前十的产品有哪些”“最近三个月用户复购率怎么样”或者“各品类的平均客单价和上个月相比有什么变化”。如果你熟练掌握了 Excel 数据透视表和 VLOOKUP这些任务确实能做但要完成一次完整的数据清理、字段合并、分组统计操作会非常繁琐。更麻烦的是一旦数据量从几千行变成几百万行Excel 会变得极其卡顿公式的运算速度也大幅下降。此时 Python 数据分析的优势就体现出来了而在 Python 的整个数据分析生态里Pandas 往往是第一块敲门砖。我的判断是对于想走数据分析路线的人Pandas 不是“可选项”而是“必须先学的那个”。它把你对数据的操作从“靠鼠标在表格里点来点去”变成“用几行代码精确表达数据处理逻辑”同时也为你后续学习数据可视化、机器学习打基础。本文的目标是帮助你用尽量短的时间建立 Pandas 的核心知识框架先跑通“读取数据 → 清洗数据 → 分组统计 → 结果输出”这条主线而不是一上来就陷入某个函数的细节。读完这篇文章你可以做到三件事第一知道 Pandas 里的核心数据结构到底是什么和 Excel、SQL 有什么区别第二能够用 Pandas 读取常见的 CSV 或 Excel 文件并完成缺失值处理、重复值删除、类型转换第三能够完成按条件筛选、分组聚合、排序和数据合并最后把结果导出成文件。2. Pandas 核心概念你和一张数据表的距离在正式开始写代码之前先把最核心的概念说清楚。Pandas 是一个基于 Python 的开源数据处理库它的名字来源于“Panel Data”和“Python Data Analysis”它构建在 NumPy 之上所以你在 Pandas 里看到的很多操作底层都是 NumPy 的数组运算。Pandas 有两个核心数据结构Series 和 DataFrame。Series 可以理解成一张表中的“一列”它包含一组数据和一个对应的索引。DataFrame 则可以理解成一张完整的“二维表格”有行有列每一列都可以看作一个 Series。如果你用过 Excel可以这样类比DataFrame 就是 Excel 里的一个工作表Series 就是工作表里的某一列。SQL 里处理的是“表”Pandas 处理的是“DataFrame”但二者不完全一样。SQL 擅长基于声明的查询而 Pandas 更灵活它允许你在内存里对数据进行非常自由的变换、清洗、分组和合并尤其是对不规则数据的处理Pandas 写起来比 SQL 直观得多。一个容易混淆的地方是Pandas 的“行索引”不一定是 0、1、2 这样的连续数字它可以是日期、字符串甚至是我们自定义的标签。这意味着 Pandas 在按行定位时有两种方式一种是按下标位置另一种是按索引标签初学者经常会在这里搞混。再看一下 Pandas、NumPy、Excel 和 SQL 各自的角色对比工具适合场景优势劣势Excel小型数据表、临时统计、报表上手快、可视化方便数据量大时卡顿操作难复用SQL存储在数据库中的结构化数据查询性能高、适合大型数据清洗和复杂变换表达受限NumPy数值计算、矩阵运算高性能、适合数学计算缺少表格层面的高级操作Pandas内存中的表格数据清洗、分析、变换灵活、功能全、和 Python 生态集成好学习曲线比 Excel 陡峭这篇文章的主角是 Pandas但你会发现我们在很多地方都会提到 NumPy因为 Pandas 的数据类型、缺失值表示等方法都来自 NumPy。3. 环境准备安装 Pandas 并确认可用Pandas 的安装并不复杂但很多新手卡在第一步。下面介绍几种常见方式。3.1 使用 pip 安装如果你的电脑已经安装了 Python最简单的方式是在命令行执行pip install pandas如果你有多个 Python 环境建议指定具体的 Python 版本对应的 pippython -m pip install pandas这样做的好处是你明确知道是把包安装在当前激活的 Python 环境里而不是某个你不太确定的环境中。3.2 使用 Anaconda 安装如果你是零基础入门数据分析更推荐直接安装 Anaconda。Anaconda 是一个 Python 发行版内置了 Pandas、NumPy、Matplotlib、Jupyter Notebook 等数据分析最常用的一整套工具。安装后你不需要逐个去配环境。conda install pandas3.3 在 PyCharm 中安装如果你使用 PyCharm 写代码可以在File - Settings - Project - Python Interpreter里点击加号搜索 pandas然后点击 Install Package。这样安装的包会绑定在当前项目的虚拟环境中不会污染系统的 Python。很多初学者在 PyCharm 里遇到 “ModuleNotFoundError: No module named pandas”大概率是因为终端里安装包的 Python 和 PyCharm 项目解释器不是同一个。3.4 验证安装安装完成后打开 Python 交互环境或新建一个 Python 文件执行import pandas as pd print(pd.__version__)如果能够输出版本号说明 Pandas 已经可以正常使用了。这里有一个约定俗成的习惯几乎所有人都会把 pandas 导入为 pd把 numpy 导入为 np你也应该遵循这个约定因为网上的大量代码和教程都基于这个缩写保持一致可以避免很多麻烦。关于版本本文不绑定具体版本号因为 Pandas 的 API 在近几个版本中变化不大你只要使用较新的稳定版本即可。如果你在安装时遇到与 Python 版本适配的问题优先查看报错信息中提示的 Python 最新支持范围再选择对应的 pandas 版本。4. 核心流程从读取数据到输出结果我想先帮你建立一个整体视图。Pandas 数据分析的主线流程其实可以压缩成六个步骤导入 Pandas 库。读取外部数据得到一个 DataFrame。查看数据的基本信息确认数据长什么样。数据清洗处理缺失值、重复值、类型转换、重命名列名。数据变换与分析筛选、排序、分组、聚合、合并。输出结果打印到屏幕或导出为 CSV、Excel 文件。下面的章节会沿着这六个步骤展开。每一步我都会给出可运行的代码并把关键点解释清楚。5. 第一步读取一份真实的数据读取数据是 Pandas 最常见的入口因为大部分数据分析任务都是从已有的 Excel、CSV 或者数据库表中开始的。5.1 用 read_csv 读取 CSV 文件CSV 是最常见的数据交换格式之一。假设你有一个名为sales.csv的文件内容大致如下order_id,city,category,amount,order_date 1001,北京,数码,2999,2024-01-05 1002,上海,服装,199,2024-01-07 1003,广州,食品,89.5,2024-02-11 1004,北京,图书,45,2024-02-15 1005,上海,数码,4599,2024-03-01注意下面代码中的文件路径是./data/sales.csv表示当前目录下的 data 文件夹。如果你把 CSV 文件放在和 Python 脚本同一个目录下直接写sales.csv即可。import pandas as pd df pd.read_csv(./data/sales.csv) print(df)运行后你会看到控制台输出一个类似表格的结构第一行是列名下面是具体数据左边会自动生成从 0 开始的整数索引。这个df就是 DataFrame。5.2 用 read_excel 读取 Excel 文件如果你的数据在 Excel 里使用df pd.read_excel(./data/sales.xlsx, sheet_nameSheet1)sheet_name参数可以指定读取哪个工作表。如果没有指定默认读取第一个工作表。这里需要提醒你的是读取 Excel 需要额外的依赖库openpyxl或xlrd如果报错可以根据提示安装。pip install openpyxl5.3 读取之后先做三件事拿到 DataFrame 之后不要着急处理先做一个初步的“体检”。# 查看前5行数据 print(df.head()) # 查看数据规模几行几列 print(df.shape) # 查看每列的非空个数和数据类型 print(df.info()) # 查看数值列的统计描述 print(df.describe())这段代码里head()默认显示前 5 行shape返回一个元组比如(5, 5)表示 5 行 5 列info()会告诉你每列有多少个非空值以及该列的数据类型describe()会给出 count、mean、std、min、max 等统计量。看懂这些输出数据的大致情况就有了。这一步非常关键因为很多时候你拿到手的数据并不像示例这么干净。读取数据后第一步永远不是急着算结果而是确认数据读进来是不是对的、有没有乱码、列名是否符合预期、有没有缺失值。如果列名是中文且乱码通常要在读取时指定编码如果是 CSV 文件常见编码是utf-8或gbk。df pd.read_csv(./data/sales.csv, encodingutf-8)如果出现乱码可以尝试encodinggbk这与 Excel 另存为 CSV 时的默认编码环境有关。6. 第二步数据清洗处理缺失值和重复值真实数据几乎不可能像示例那样整齐你一定会遇到缺失值、重复值、格式不统一等问题。这一节是 Pandas 实操里最耗时间的地方却是最能体现分析价值的部分。6.1 查看缺失值现在假设数据中有几行缺少amount或city。你可以用以下方式统计缺失情况# 统计每列缺失值数量 print(df.isnull().sum())输出结果会按列显示缺失数量。这里的isnull()返回的是与原表结构相同的布尔值表为 True 表示空值再调用.sum()True 会被当成 1 来计算所以得到的是每列缺失总数。6.2 删除缺失值如果你的数据量足够大缺失值占比很低最简单的方案是直接删除包含缺失值的行df_clean df.dropna()dropna()默认会删除任何包含缺失值的行。你也可以指定只针对某些列df_clean df.dropna(subset[amount])意思是只检查amount这一列如果该列为空才删除对应行。6.3 填充缺失值如果不想删除数据可以用fillna()填充。比如用 0 填充数值列或者用该列的均值填充df[amount] df[amount].fillna(0) # 用均值填充 df[amount] df[amount].fillna(df[amount].mean()) # 用前一个有效值填充 df[city] df[city].fillna(methodffill)方法ffill是 forward fill可以理解为用上一行的值填充当前空值适合处理时间序列数据。6.4 删除重复值一个很常见的需求是如果两行数据在某些指定列上的值完全相同则只保留第一条。这正是热搜词里的一个经典场景。在 Pandas 中用drop_duplicates()就可以实现。只看前两列来判断重复并保留第一条df_unique df.drop_duplicates(subset[order_id, city], keepfirst)这里subset表示按哪些列判断重复keepfirst表示保留重复行中的第一条。如果你想让重复值全部删掉一条都不留可以写成df_unique df.drop_duplicates(subset[order_id, city], keepFalse)在实际业务里“两条记录是否算重复”往往取决于业务规则是订单号和城市完全一致就算重复还是所有字段完全一致才算重复。这个判断一定要提前和业务方确认清楚不能想当然。6.5 数据类型转换info()的结果里会显示每一列的类型。类型不对会导致后续排序、计算、日期处理全部出错。经常需要处理的有两种情况。第一种把字符串类型转成数值类型df[amount] pd.to_numeric(df[amount], errorscoerce)errorscoerce的意思是把无法转换的内容变成缺失值而不是直接报错。比如某行amount是“-”这个符号转换后会被置为 NaN。第二种把字符串转成日期时间类型df[order_date] pd.to_datetime(df[order_date])转换之后我们可以很方便地提取年份、月份df[year] df[order_date].dt.year df[month] df[order_date].dt.month很多新手在这里会犯一个错误以为转完类型后原列就自动生效了。实际上如果你没有把结果重新赋值给原列比如只写pd.to_numeric(df[amount])而不加前面的df[amount] 数据类型是不会被更新的。6.6 重命名列名列名经常会带有空格、中文、特殊符号操作起来很不方便。推荐统一改为英文小写加下划线的风格df df.rename(columns{ order_id: order_id, 城市: city, 销售金额: amount })7. 第三步筛选、分组与聚合数据清洗完之后就进入最核心的分析环节。你基本上只会用到四类操作按条件筛选、排序、分组聚合、合并表。7.1 按条件筛选如果你要查看city等于“北京”的所有订单beijing df[df[city] 北京] print(beijing)如果你要查看金额大于 1000 的订单high_amount df[df[amount] 1000]如果你要同时满足两个条件注意要使用并且每个条件都要加上括号beijing_high df[(df[city] 北京) (df[amount] 1000)]7.2 排序按金额从高到低排序df_sorted df.sort_values(byamount, ascendingFalse)排序不会改变 DataFrame 本身除非你传inplaceTrue但我不推荐在新代码里使用inplaceTrue。更推荐的做法是显式赋值给新的变量这样代码可读性更高也不容易触发修改原数据的警告。7.3 分组聚合分组聚合是 Pandas 最重要的能力之一也是从“会读表”走向“会分析”的分水岭。比如按城市统计销售总额city_sum df.groupby(city)[amount].sum() print(city_sum)这段代码的意思是先把数据按city分组然后对每一组的amount列求和得到每个城市的销售总额。如果需要同时计算多个统计量city_stats df.groupby(city)[amount].agg([sum, mean, count, max]) print(city_stats)agg可以接收一个列表一次算出多种聚合结果。这比分别写四个 groupby 要高效得多也是 Pandas 的一个招牌写法。按城市和月份两个维度同时分组monthly_city df.groupby([city, df[order_date].dt.month])[amount].sum()这一行代码会生成一个层级索引的 Series外层是城市内层是月份。7.4 数据合并在真实业务里数据往往分散在不同表中。比如订单表只在orders.csv而产品分类信息在另一个表里这时候需要合并。Pandas 的merge和 SQL 里的 join 很相似。orders pd.read_csv(./data/orders.csv) products pd.read_csv(./data/products.csv) merged pd.merge(orders, products, onproduct_id, howleft)howleft表示左连接以左边的订单表为基础能匹配到产品信息就填充匹配不到就填 NaN。如果两边的列名不一致你需要分别指定left_on和right_on。如果你想把多个结构相同的 DataFrame 上下拼接用pd.concatdf_all pd.concat([df_q1, df_q2, df_q3], ignore_indexTrue)ignore_indexTrue的意思是重新生成连续的索引否则拼接后的 DataFrame 里会有很多重复索引新手经常被这个吓到。8. 第四步快速可视化直观看数据结论Pandas 本身不是可视化库但它和 Matplotlib 的集成非常方便你可以用一两行代码快速画图。这个能力在日常探索性分析中非常有用。先安装 Matplotlibpip install matplotlib然后用一行代码画柱状图import matplotlib.pyplot as plt import pandas as pd # 假设已经得到城市销售总额 city_sum df.groupby(city)[amount].sum() city_sum.plot(kindbar) plt.title(各城市销售总额) plt.xlabel(城市) plt.ylabel(销售金额) plt.show()在这段代码里city_sum是一个 Series它自带plot()方法。kindbar表示柱状图你也可以改成line画折线图。这里的关键点是Pandas 画图的结果仍然是一个 Matplotlib 图形所以后续的plt.title()、plt.xlabel()都能生效。对于数据分析入门来说可视化的价值不是让图多好看而是帮助你在分析过程中快速发现异常值、趋势和分布规律。比如你画完折线图后突然发现某个月的数据骤降再去查数据原因可能就找到了数据缺失或者业务活动调整的线索。这是可视化的“探索性”价值。9. 常见问题与排查思路Pandas 报错是每个初学者都会遇到的事情。下面这张表列出最常见的问题和解决思路。问题现象可能原因排查方式解决方案ModuleNotFoundError: No module named pandas当前 Python 环境没有安装 pandas检查 PyCharm 解释器和 pip 安装环境是否一致在对应环境执行 pip install pandas读取 CSV 后中文乱码文件编码不是 utf-8打印前几行查看乱码形式尝试 encodinggbk 或 encodingutf-8SettingWithCopyWarning: A value is trying to be set on a copy基于筛选后的副本修改数据查看代码中是否对 df[df[city]北京] 赋值使用 .loc 修改或先 .copy() 后再操作ValueError: cannot convert float NaN to integer含缺失值的列转整数类型检查该列是否为空先 fillna 再转换或用 errors 参数处理Pandas 版本兼容问题安装环境和 Python 版本不匹配查看 pip 报错信息升级 Python 或安装对应版本 pandasdate 列无法转换日期格式不统一打印异常行的原始内容先用字符串处理统一为 yyyy-mm-dd再 to_datetimeDataFrame 输出省略号默认显示限制查看是否有多个列被隐藏使用 pd.set_option(display.max_columns, None)再补充一个非常常见的细节df[df[city] 北京]返回的是一个视图还是副本在 Pandas 内部并不总是容易判断。如果你对这个条件筛选后的结果做修改很容易触发SettingWithCopyWarning。最稳妥的做法是当你确定要复制一份数据来做独立操作时显式调用.copy()beijing df[df[city] 北京].copy()10. 最佳实践与工程建议Pandas 入门并不难难的是从“能运行”到“能稳定复用”。下面这几条建议是我认为新手最容易忽略、但长远受益最大的点。10.1 尽量用链式操作但要控制复杂度Pandas 支持链式写法比如result ( df[df[amount] 0] .groupby(city)[amount] .sum() .sort_values(ascendingFalse) )这种写法可读性好也方便调整中间步骤。但如果链条太长出了问题反而难以排查。建议以“一个分析目标”为界把链式操作拆成两到三个中间变量。10.2 写代码时保留原始数据备份数据清洗是破坏性操作。不要直接在原始 DataFrame 上反复修改宁愿每次清洗出一个新的 DataFrame保留一份原始数据的只读备份。如果你觉得内存不够也可以把清洗后的数据写回文件再在后续步骤中读取。10.3 格式化输出结果很多分析结果最终要发给别人看把结果导出成 CSV 或 Excel 是常见需求。result.to_csv(./output/city_summary.csv, indexFalse, encodingutf-8-sig)这里有两个细节值得注意第一indexFalse表示不把索引列写入文件否则导出的文件会多出一列第二如果你之后要用 Excel 打开导出的 CSV编码建议使用utf-8-sig这个编码在 Excel 中不会出现中文乱码。如果要导出为 Excelresult.to_excel(./output/city_summary.xlsx, indexFalse)导出 Excel 同样需要openpyxl。10.4 不要把大数据全部交给 PandasPandas 的数据默认加载在内存中。如果数据量达到数 GB 甚至更大你需要先考虑是否需要抽样分析、分块读取还是直接使用 SQL 或 Spark 等分布式方案。Pandas 擅长的是灵活分析和适度规模的数据处理它不是一个数据库也不是一个数据仓库。10.5 合理利用向量化操作Pandas 的效率问题大多出在循环上。新手容易写出这样的代码# 不推荐 for i in range(len(df)): df.loc[i, amount_category] high if df.loc[i, amount] 1000 else low更推荐用向量化写法df[amount_category] np.where(df[amount] 1000, high, low)这里用到了 NumPy 的where它比 Python 循环快得多。这个例子也解释了为什么 Pandas 和 NumPy 总是成对出现你会在很多 Pandas 场景下直接使用 NumPy 函数。11. 总结与后续学习方向现在回头看你已经走过的路径从安装 Pandas、读取 CSV、检查数据到清洗缺失值、删除重复值、转换类型再到筛选、分组聚合、合并表最后把结果可视化并导出。这一条线实际上完成了一个非常典型的数据分析闭环它贯穿了日常大部分基础分析任务。如果你用两小时跟着这篇文章走一遍你会留下一个很重要的体感Pandas 并不神秘它就是把“你想对表格做的每一步操作”翻译成一行代码。真正需要花时间练习的是如何把这些步骤组合起来解决一个具体业务问题比如“按城市统计月度销售趋势”“找出复购用户”等等。接下来按优先顺序我建议你这样继续深入第一把官方 DataFrame 和 Series 的常用方法过一遍不必全记但要知道有什么功能。第二上手做一个完整的小项目比如分析一份开源的数据集跑通数据清洗、分组、可视化全流程。第三如果你想做更复杂的数据分析可以学习 SQL、数据可视化库或机器学习入门因为 Pandas 是这些方向的基础而不是终点。数据分析的学习曲线并不陡峭但它非常依赖“动手做”。每拿到一份新数据都建议从头开始读取、体检、清洗、分析、输出这个套路反复用你会慢慢形成自己的分析习惯。希望这篇文章能成为你的第一份 Pandas 实战笔记也建议收藏备用等到实际写代码时再对照一遍会比只看不动收获更大。
返回列表