ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Pandas数据分析速通:从数据读取到聚合导出的完整实战流程

Pandas数据分析速通:从数据读取到聚合导出的完整实战流程 如果你点进这篇文章大概率已经受够了“看完教程就忘、一跑代码就报错”的Pandas学习体验。Pandas确实不难但它的知识点非常零散DataFrame、Series、索引、清洗、聚合、透视表每一个单独看都能看懂合在一起面对真实数据时就不知道从哪下手。这篇文章的价值就是帮你把零散的知识点串成一条清晰的技能链用一套可复用的方法论在最短时间内掌握Pandas做数据分析的核心能力。先说一个明确判断Pandas数据分析真正重要的不是把所有API背下来而是掌握“数据容器—数据读取—数据清洗—数据转换—数据聚合—数据导出”这条主线。2小时速通的关键是沿着主线走一遍真实的数据分析流程而不是按官方文档从头翻到尾。读完这篇文章你会得到一套完整可运行的分析代码模板以后再遇到CSV、Excel、Parquet等格式的数据都能直接套用这套流程。1. 这篇文章真正要解决的问题很多人学Pandas最大的痛点不是“不会写代码”而是“不知道下一步该干什么”。拿到一份数据后是先用head()看数据还是先info()看类型缺失值到底是删还是填重复数据怎么按指定列去重类型转换为什么总是报错这些问题如果靠零散搜索去解决每次都要花大量时间。Pandas作为Python数据分析的核心库承担的是数据处理中“脏活累活”的部分。它把Excel操作、SQL查询、甚至部分Spark功能浓缩到一个Python库中让数据分析师可以不依赖数据库和Excel宏纯用代码完成整个分析流程。更重要的是Pandas的语法设计非常贴近人的思考方式你想着“按城市分组算平均销售额”代码就是df.groupby(城市)[销售额].mean()几乎没有中间转换成本。这篇教程的目标读者非常明确有Python基础但没系统学过Pandas的人学过Pandas但只会单个函数、不会串流程的人以及准备用Python做数据分析或数据清洗需要一套可复用模板的人。如果你已经有丰富的Pandas实战经验这篇文章对你偏基础但其中的数据清洗细节和格式转换案例仍值得扫一眼。2. Pandas核心概念DataFrame、Series与索引Pandas最核心的两个数据结构是DataFrame和Series理解它们的区别是后续所有操作的基础。2.1 Series一列数据Series是Pandas的一维数据结构可以理解为“带标签的一列数据”。它由两部分组成索引index和数据值values。索引默认是0到n-1的整数但也可以是日期、字符串等自定义标签。import pandas as pd s pd.Series([10, 20, 30, 40], index[A, B, C, D]) print(s) print(s[B]) # 输出 20在数据分析中Series通常是从DataFrame中取出一列的结果比如df[销售额]返回的就是一个Series。理解Series是理解DataFrame的基础因为DataFrame本质上是由多个Series共享同一个索引组成的二维表。2.2 DataFrame二维表DataFrame是Pandas的二维表格数据结构既有行索引也有列名。它就像一张Excel表每一列可以是不同的数据类型这是它与NumPy二维数组最大的区别NumPy数组要求所有元素类型一致而DataFrame允许一列是整数、一列是字符串、一列是日期。data { 姓名: [张伟, 李娜, 王强, 赵敏], 城市: [北京, 上海, 广州, 深圳], 销售额: [12000, 15000, 9800, 13200] } df pd.DataFrame(data) print(df)创建DataFrame最常用的方式是从字典创建字典的键是列名值是对应列的列表。实际分析中更多是通过读取CSV、Excel等文件直接得到DataFrame。2.3 索引的真正含义Pandas里的索引非常特殊它不只是“第几行”还是一个对齐工具。当两个DataFrame用运算时Pandas会按照索引标签自动对齐而不是按位置对齐。这个特性在日常操作中经常造成意想不到的结果新手要注意。s1 pd.Series([1, 2, 3], index[A, B, C]) s2 pd.Series([10, 20, 30], index[B, C, D]) print(s1 s2) # A和D位置的结果是NaN因为索引没有对齐输出结果中A和D位置是NaN就是因为Pandas按索引做加法找不到对应索引的位置就返回缺失值。这个机制是Pandas强大之处也是新手容易掉坑的地方。2.4 用一句话总结概念Series是带标签的一维数组DataFrame是带行列标签的二维表索引是Pandas实现数据对齐和灵活定位的关键。建议学习时把DataFrame想成Excel表把索引想成Excel左侧的行号但Pandas的索引比Excel行号更灵活它可以是任意值。3. 环境准备安装Pandas与版本选择开始写代码之前先把环境准备好。这一步看起来简单但版本不匹配导致的问题非常多。3.1 安装Pandas最常见的安装方式是通过pip安装pip install pandas如果你使用的是Anaconda推荐用conda安装依赖管理更省心conda install pandas如果你在PyCharm中使用可以通过File - Settings - Project - Python Interpreter点击加号搜索pandas进行安装。也可以直接在PyCharm底部的Terminal中执行pip install pandas。3.2 Python版本适配说明关于版本适配这里有一个高频问题需要说明清楚Python 3.10到底配哪个版本的Pandas从Pandas官方发布记录来看Pandas 1.5.0开始支持Python 3.10所以Python 3.10环境最低应该安装Pandas 1.5.0以上版本。如果你使用的是最新版Pandas 2.x同样支持Python 3.10但请注意Pandas 2.x部分API有调整比如append方法被移除、部分字符串方法被迁移到.str访问器。稳妥的做法是Python 3.10配Pandas 1.5.x到2.0.x都可以Python 3.11以上建议直接用最新版。安装后验证版本import pandas as pd print(pd.__version__)如果你在导入Pandas时报错ImportError: Missing required dependencies [numpy]说明NumPy没有正确安装重新执行pip install numpy pandas即可。3.3 一个清爽的测试脚本建议先跑一个最小脚本确认环境没问题# 文件: test_pandas.py import pandas as pd df pd.DataFrame({a: [1, 2, 3], b: [4, 5, 6]}) print(df.head()) print(Pandas环境OK)执行后如果能正常输出表格和提示信息说明环境已经就绪可以进入下面的实战环节。4. Pandas数据读取从CSV、Excel、Parquet、Feather说起环境准备好之后第一个实战任务就是读取数据。这看起来简单但读数据的坑非常多尤其是文件编码和格式选择。4.1 读取CSV文件CSV是最常见的数据存储格式。Pandas读取CSV的核心函数是read_csv()import pandas as pd df pd.read_csv(sales_data.csv, encodingutf-8) print(df.head())如果文件是GBK编码读取时会出现UnicodeDecodeError这是中文环境里最经典的报错。解决方案是更换编码参数df pd.read_csv(sales_data.csv, encodinggbk)从实际经验来看Windows环境下用Excel另存的CSV默认是GBK编码从网站导出的CSV大多是UTF-8编码。如果两种编码都报错可以用encodinggb18030它是GBK的超级兼容性更好。4.2 读取Excel文件读取Excel需要额外安装openpyxl或xlrd库pip install openpyxldf pd.read_excel(sales_data.xlsx, sheet_nameSheet1)注意read_excel默认读取第一个sheet指定sheet_name参数可以读取指定工作表。如果你有Excel文件但没装openpyxl会直接报错ImportError: Missing optional dependency openpyxl按提示安装即可。4.3 读取Parquet和Feather更快的格式选择这里要重点说一个容易被忽略但实战价值很高的话题当数据文件很大比如几GBCSV的读取速度会明显变慢。这时候Parquet和Feather这两种列式存储格式就非常有用了。Parquet和Feather的共同特点是压缩率高、读取速度快、保留数据类型信息。CSV存入的是字符串读取时需要重新推断类型而Parquet和Feather直接以二进制格式保存读取时不需要类型推断所以速度往往快数倍。# 读取Parquet df pd.read_parquet(sales_data.parquet) # 读取Feather df pd.read_feather(sales_data.feather)同样保存数据时也可以选择这两种格式df.to_parquet(sales_data_output.parquet) df.to_feather(sales_data_output.feather)使用read_parquet需要安装pyarrow或fastparquetpip install pyarrow这个知识点在网上的Pandas教程中经常被忽略但在离线数据分析、金融风控数据分析等需要处理大规模数据的场景中Parquet几乎已经是标准格式。值得一提的是Pandas提供的这些读写能力非常适合轻量替代Spark部分功能如果数据量还在单机内存能装下的范围内用Pandas配合Parquet格式比引入Spark集群简单得多维护成本也更低。4.4 快速查看数据规模的通用方法无论读取什么格式拿到DataFrame后的第一个动作是确认数据规模print(df.shape) # 输出(行数, 列数) print(df.dtypes) # 输出每列的数据类型 print(df.columns) # 输出所有列名这三个操作能让你在10秒内对数据建立整体认知。如果shape返回的行数和列数和你预期不一致优先怀疑读取时指定了错误的参数。5. 数据探索快速了解数据全貌读取数据之后不要急着清洗先做探索性分析。这一步的目的是确认数据质量、发现明显问题。5.1 查看前几行数据print(df.head()) # 前5行 print(df.tail()) # 后5行5.2 查看整体信息print(df.info())info()输出每列的非空数量、数据类型、内存占用。这一步就能快速发现哪些列有缺失值哪些列类型不对。比如“销售额”列显示为object类型那基本可以确定这一列混入了非数字字符后面需要做类型转换。5.3 描述性统计print(df.describe())describe()对数值列输出均值、标准差、最小值、四分位数、最大值。这一步能发现明显的异常值比如销售额最大值为负数或者年龄列最小值为0这些都可能表示数据录入错误。5.4 缺失值总览print(df.isnull().sum())这一行代码统计每列缺失值的数量是数据清洗前的必要步骤。缺失值比例超过30%的列如果业务上不重要可以直接删除如果重要则需要用填充策略处理。6. 数据清洗实战缺失值、重复值与列操作数据清洗是Pandas数据分析中最耗时、最核心的环节。真实数据通常存在问题缺失、重复、异常、类型混乱。把这段练熟你就解决了数据分析一半以上的工作量。6.1 缺失值处理Pandas中的缺失值用NaN表示。处理缺失值有两种策略删除和填充。# 删除包含缺失值的行 df_cleaned df.dropna() # 删除某列为空的行更常用 df_cleaned df.dropna(subset[销售额]) # 用0填充数值列的缺失值 df_cleaned df.fillna({销售额: 0}) # 用前一个有效值填充适用于时间序列 df_cleaned df.fillna(methodffill)删除还是填充取决于业务场景。如果缺失比例很低5%直接删除如果缺失比例较高但列重要一般用均值、中位数或业务默认值填充。这里推荐一个实战原则先计算缺失比例再决定策略不要盲目dropna()。6.2 重复值处理重复值分为行完全重复和部分列重复两种情况。# 查看重复行的数量 print(df.duplicated().sum()) # 删除完全重复的行 df_cleaned df.drop_duplicates() # 按指定列去重保留第一条 df_cleaned df.drop_duplicates(subset[用户ID]) # 按指定列去重保留最后一条 df_cleaned df.drop_duplicates(subset[用户ID], keeplast)这里重点扩展一个高频场景如果指定两列的值均相同则保留第一条数据。这个需求在订单表、用户行为表中非常常见。比如有一张用户登录记录表每次登录都会产生一条记录现在要分析“每个用户在某个渠道的第一条记录”就需要按用户ID和渠道两列去重。# 文件: dedup_demo.py import pandas as pd df pd.DataFrame({ 用户ID: [1, 1, 2, 2, 3], 渠道: [A, A, B, B, A], 登录时间: [2025-01-01, 2025-01-02, 2025-01-01, 2025-01-03, 2025-01-02] }) df_cleaned df.drop_duplicates(subset[用户ID, 渠道], keepfirst) print(df_cleaned)运行结果会保留每个“用户ID渠道”组合的第一条记录。很多学习Pandas的人在这里会困惑为什么我用了drop_duplicates()但还有重复大概率是忘记指定subset参数默认是对所有列去重而不是按指定列去重。如果想在去重前按时间排序确保保留的是最新一条df[登录时间] pd.to_datetime(df[登录时间]) df_sorted df.sort_values(登录时间) df_cleaned df_sorted.drop_duplicates(subset[用户ID, 渠道], keeplast)这个“先排序再去重”的技巧在日常数据分析中非常实用。6.3 列重命名与筛选数据清洗阶段经常需要修改列名。Pandas推荐使用rename()df_cleaned df.rename(columns{用户ID: user_id, 销售额: sales})选择需要的列用方括号加列表df_selected df[[user_id, sales]]6.4 条件筛选条件筛选是数据分析中使用频率最高的操作。# 筛选销售额大于10000的记录 df_filtered df[df[销售额] 10000] # 多条件筛选城市为北京且销售额大于10000 df_filtered df[(df[城市] 北京) (df[销售额] 10000)] # 筛选销售额在10000到20000之间的记录 df_filtered df[df[销售额].between(10000, 20000)] # 筛选城市属于指定列表的记录 df_filtered df[df[城市].isin([北京, 上海])]这里有个新手最常见的报错and和or在NumPy/Pandas中不能直接用必须用和|。原因是在Series上使用and时Python无法判断整个Series的布尔值因此必须用位运算符。另外每个条件外面要加括号()因为的优先级高于比较运算。7. 数据类型转换最容易被忽视的环节数据类型转换是Pandas数据分析中报错率最高的地方。很多讲师会跳过这个知识点因为它看起来很简单但实际项目中80%的运算报错都源于类型不对。Pandas常见的数据类型有int64、float64、object通常为字符串、datetime64、bool、category。7.1 检查类型print(df.dtypes)7.2 数值类型转换# 字符串转整数注意列内容必须是数字字符串 df[用户ID] df[用户ID].astype(int64) # 字符串转浮点数 df[销售额] df[销售额].astype(float64)如果列中含有空白字符或无法转换的内容astype会直接报错ValueError。这时候需要用to_numeric()配合errors参数处理# 无法解析的转为NaN df[销售额] pd.to_numeric(df[销售额], errorscoerce)errorscoerce的意思是遇到无法转换的值就变成NaN而不是直接报错。这是实战中最常用的转换方式因为真实数据的脏值远比你想象的复杂。7.3 字符串转日期日期处理是Pandas数据分析中另一大重点。# 字符串转日期 df[登录日期] pd.to_datetime(df[登录日期])转换后就可以提取年月日、星期等信息df[年份] df[登录日期].dt.year df[月份] df[登录日期].dt.month df[星期] df[登录日期].dt.day_name() df[是否周末] df[登录日期].dt.weekday 5日期列在转换前是object类型不能直接比较大小也不能按时间排序。转换后再配合过滤、排序、重采样就能处理各种时间序列分析需求。7.4 Excel与Python数据处理的对比思考有一个热搜词是“excel python飞速搞定数据分析与处理 pdf”这背后说明一个趋势很多原本靠Excel做数据分析的人也在尝试转向PythonPandas。这种转变的原因很简单Excel处理几万行数据就卡顿Pandas处理几百万行依然流畅Excel录制宏写代码门槛不低Pandas的代码逻辑清晰可复用还能直接对接后续的机器学习流程。如果你已经熟悉Excel的数据透视表Pandas的pivot_table几乎是平移学习成本后面的章节会演示。8. 分组聚合groupby与统计分析分组聚合是Pandas数据分析中价值最高的操作它的作用相当于Excel透视表和SQL中的GROUP BY。8.1 分组计算# 按城市分组计算销售额的平均值 result df.groupby(城市)[销售额].mean() print(result) # 按城市分组计算销售额总和 result df.groupby(城市)[销售额].sum()如果既要平均值又要总和可以用agg()一次算多个指标result df.groupby(城市)[销售额].agg([sum, mean, count, max, min]) print(result)8.2 多列分组与多列聚合result df.groupby([城市, 商品类别])[销售额].agg([sum, mean]).reset_index()注意reset_index()的作用Pandas分组聚合后分组字段会被放到索引中用reset_index()可以把索引恢复成普通列。这样更方便后续操作和导出。这是新手最容易忽略的一步分组后如果直接to_csv()会发现分组字段没有作为列导出。8.3 透视表如果你熟悉Excel透视表Pandas的pivot_table会让你觉得无比亲切pivot pd.pivot_table( df, values销售额, index城市, columns商品类别, aggfuncsum, fill_value0 ) print(pivot)这个操作在商业数据分析中非常常用行是城市列是商品类别交叉点是销售额总和。fill_value0的作用是把空值填为0这样透视表看起来更干净。8.4 实战中的分组场景金融风控数据分析中分组聚合常用于计算每个用户的总交易金额、平均单笔金额、交易频次电商数据分析中常用于计算每个商品类别的销售汇总体育数据分析比如热搜中的足球数据分析中常用于按球队、赛季聚合比赛数据。掌握groupby加agg这一组组合你就能应对大部分“按XX计算XX”的需求。9. 多表连接像SQL一样合并数据真实项目中的数据很少只有一张表。用户信息在一张表、订单记录在另一张表、商品信息在第三张表分析时经常需要将它们合并。Pandas的merge()与SQL中的JOIN对应。9.1 内连接与外连接# 内连接只保留两边都匹配的记录 merged pd.merge(df_orders, df_users, on用户ID, howinner) # 左连接保留左侧表全部记录右侧表匹配不到的填充NaN merged pd.merge(df_orders, df_users, on用户ID, howleft) # 右连接 merged pd.merge(df_orders, df_users, on用户ID, howright) # 全连接 merged pd.merge(df_orders, df_users, on用户ID, howouter)9.2 concat纵向拼接如果两张表结构相同需要上下拼接用concat()df_all pd.concat([df_1月, df_2月], ignore_indexTrue)ignore_indexTrue会重新生成连续索引避免拼接后索引重复。这里需要说明的是在Pandas 2.0及以上版本append方法已被移除统一使用concat。9.3 一个实际合并案例假设有两张表订单表和用户表。订单表有用户ID用户表有用户ID和城市、年龄信息。合并后就可以按城市对订单做聚合分析df_merged pd.merge(df_orders, df_users, on用户ID, howleft) result df_merged.groupby(城市)[订单金额].sum().reset_index() print(result)这就是典型的“先关联、后聚合”分析流程。10. 数据导出分析结果落地分析做完结果需要导出。Pandas支持多种导出格式这里选择最常用的三种。10.1 导出为CSVdf_result.to_csv(analysis_result.csv, indexFalse, encodingutf-8-sig)这里特别强调两个参数indexFalse不导出索引否则文件里会多出一列无意义的序号encodingutf-8-sig适合中文场景用Excel打开时不会出现乱码。如果导出后用Excel打开乱码大概率就是encoding参数没有加-sig。10.2 导出为Exceldf_result.to_excel(analysis_result.xlsx, indexFalse, sheet_name结果)10.3 导出为Parquet如果数据量大或者后续还要用Python处理推荐导出为Parquetdf_result.to_parquet(analysis_result.parquet, indexFalse)11. 完整案例从原始CSV到分析报告为了把前面所有知识点串联起来这里演示一个完整的数据分析流程。假设我们有一份销售订单数据sales_orders.csv包含字段订单编号、用户ID、城市、商品类别、订单金额、下单日期。# 文件: sales_analysis.py import pandas as pd # 1. 读取数据 df pd.read_csv(sales_orders.csv, encodingutf-8) print(原始数据规模, df.shape) # 2. 数据预览 print(df.head()) print(df.info()) # 3. 数据清洗删除订单金额为空的行 df df.dropna(subset[订单金额]) # 4. 订单金额转为数值 df[订单金额] pd.to_numeric(df[订单金额], errorscoerce) df df.dropna(subset[订单金额]) # 5. 日期转换 df[下单日期] pd.to_datetime(df[下单日期]) df[月份] df[下单日期].dt.month # 6. 去除重复订单 df df.drop_duplicates(subset[订单编号], keepfirst) # 7. 按城市统计订单金额 summary_city df.groupby(城市)[订单金额].agg([sum, mean, count]).reset_index() print(summary_city) # 8. 按月份统计订单金额 summary_month df.groupby(月份)[订单金额].sum().reset_index() print(summary_month) # 9. 透视表城市 x 商品类别 销售额 pivot pd.pivot_table(df, values订单金额, index城市, columns商品类别, aggfuncsum, fill_value0) print(pivot) # 10. 导出结果 summary_city.to_csv(城市销售汇总.csv, indexFalse, encodingutf-8-sig) summary_month.to_csv(月度销售汇总.csv, indexFalse, encodingutf-8-sig) pivot.to_csv(城市类别透视表.csv, encodingutf-8-sig)这段代码覆盖了读取、预览、清洗、转换、去重、分组、聚合、透视、导出全流程。建议把它完整跑一遍然后替换成你自己的数据文件反复演练直到熟练。12. 常见问题与排查方法下面是Pandas新手最常遇到的几类问题建议收藏备用。问题现象可能原因排查方式解决方案导入Pandas报ImportError环境未安装pandas或numpy依赖缺失执行pip list查看已安装包执行pip install numpy pandas读取CSV报UnicodeDecodeError文件编码与指定编码不一致用文本编辑器查看文件编码切换encodinggbk或encodingutf-8astype转换报ValueError字符串列中含有无法转换的字符先pd.to_numeric(col, errorscoerce)用coerce转NaN后再处理缺失值条件筛选报“The truth value of a Series is ambiguous”在Series上用了and而不是检查条件连接运算符改为每个条件加括号分组后导出发现分组字段丢失分组字段在索引中打印结果查看索引分组后加reset_index()DataFrame没有append方法Pandas版本在2.0以上查看Pandas版本pd.__version__改用pd.concat([df1, df2])导出CSV用Excel打开乱码编码不是utf-8-sig用记事本打开确认导出时指定encodingutf-8-sigExcel文件读取失败缺少openpyxl或xlrd查看报错提示缺少的依赖执行pip install openpyxl13. 最佳实践与工程建议按照上面的内容你已经掌握了Pandas的核心操作。最后补充几个在真实项目中总结的工程建议这些经验能帮你少走很多弯路。13.1 数据清洗先行分析后置拿到数据不要急着画图或建模先用info()、isnull().sum()、duplicated().sum()做全面体检。清洗工作就像做饭前的洗菜切菜跳过这一步后面所有的“烹调”都会受到影响。建议把清洗流程封装成函数每次拿到新数据直接调用形成标准化流程。13.2 善用链式操作Pandas 2.x推荐使用df.pipe()或写清晰的多行链式操作避免变量越写越多df_clean ( df.copy() .dropna(subset[订单金额]) .drop_duplicates(subset[订单编号]) .assign(下单日期pd.to_datetime(df[下单日期])) )这种方式代码更容易阅读和维护也更容易放进函数里复用。使用copy()是为了避免Pandas的SettingWithCopyWarning报警这是一个非常常见但又容易被人忽略的坑。13.3 处理大型数据时考虑Parquet和Feather如果数据文件超过1GB建议不要再使用CSV作为中间存储格式改用Parquet或Feather。两者的差别在于Parquet压缩率更高适合长期存储和跨系统交换Feather读写速度更快适合分析过程中的临时缓存。如果你在做离线数据分析又不想引入Spark等分布式框架Pandas加Parquet是门槛最低、见效最快的组合。13.4 动手完成一个综合性分析项目学习Pandas最有效的方式不是看教程而是动手完成一个项目。你可以从身边的数据开始导出一份电商平台的订单数据或者从公开数据网站下载一份真实数据集按本文的流程独立完成清洗、聚合和可视化。第一次做可能比较慢但完整跑完一遍后你对Pandas的理解会完全不同。Pandas作为Python数据科学生态中最核心的库之一真正掌握它并不需要记住每一个API而是需要理解数据从“原始”到“干净”再到“有结论”这个过程需要哪些步骤。本文给出的流程模板就是你现在最需要掌握的技能路线按照这套路线从陌生到能独立完成数据分析工作并没有想象中那么远。
返回列表