尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Python数据分析全链路:从数据收集到预测建模的pandas实战指南

Python数据分析全链路:从数据收集到预测建模的pandas实战指南 简介《使用 Python 进行数据分析》是一份系统讲解数据分析流程与 Python 核心库应用的 DOCX 教程文档面向希望从零开始掌握 NumPy、Pandas、Matplotlib 及探索性数据分析EDA的入门读者。文档先梳理数据分析的六个关键步骤明确要求、收集数据、清洗加工、分析、共享与报告再按工具逐层展开在 NumPy 部分除数组创建、empty/zeros 初始化、索引与切片外还介绍了数组的秩、形状以及加减乘除算术运算并说明基础切片返回视图、数组索引返回副本等易混淆概念Pandas 部分重点讲解 DataFrame 这一二维异质表格结构用于处理带行列标签的常见数据集Matplotlib 部分则展示如何绘制出版级别图表配合统计图与数据挖掘手段完成 EDA找到变量关系与异常值。资源包仅含 1 个 docx 文件压缩包大小约 2.05MB内容紧凑、目录清晰可作为自学笔记或课程讲义。目前已有 46 人学习下载适合数据分析初学者、转行者以及希望系统梳理 Python 数据工具链的读者。1. 用 Python 做数据分析前先认清收集、转换、组织这条主链路手上拿到一张三万行的销售明细表老板问下个季度哪个品类会涨直接打开 Jupyter 就建模的人多半会在数据质量上翻车。数据分析的产出物不是模型是决策依据而依据靠不靠谱取决于数据在进入算法之前被收集得全不全、转换得干不干净、组织得合不合理。Python 在这条链路里的位置很固定pandas 负责读数和清洗numpy 负责向量化计算matplotlib 负责把结论变成可交付的图sklearn 负责最后一步规律验证。环境上不需要多复杂Python 3.9 以上装好 pandas 一套就能开跑。下面按收集、转换、组织、预测的次序展开每个环节给最小可跑的代码和参数边界。适合刚把 Python 语法过完、准备做第一个数据项目的工程师也适合看了不少教程但总在真实数据上卡壳的人。2. 用 Python 收集数据CSV、Excel 与数据库的读取参数怎么设收集阶段的目标是把数据完整搬进内存同时保留原始信息。常见误区是拿到文件就read_csv编码不对报错再换类型不对再回头改。多花三分钟把参数定清楚后面转换阶段能少踩一大片坑。2.1 最小可跑的 read_csv 命令编码、类型、日期一次设对以一份销售明细 CSV 为例import pandas as pd df pd.read_csv( sales_2024.csv, encodingutf-8-sig, # 带 BOM 的 Excel 导出文件用这个编码 dtype{会员ID: str}, # 会员ID 按文本读不能被转成数值 parse_dates[下单时间], # 需要时间分析的列直接解析成 datetime ) print(df.shape) print(df.dtypes) df.head()dtype解决的是ID 被读成 float的经典问题00123这种带前导零的编号不指定类型会被读成数值 123信息直接丢失。parse_dates比事后pd.to_datetime更省事读取阶段就把时间列转成 datetime64后续按小时、按天聚合不用再转换。encoding用utf-8-sig而不是utf-8是因为 Windows 下导出的 CSV 常带 BOM 头直接按 utf-8 读会让第一列列名出现\ufeff前缀groupby 时对不上列名。# 大文件不想让分块推断导致类型前后不一致 df_fast pd.read_csv(large_file.csv, dtypestr, low_memoryFalse)low_memory容易被忽略。默认情况下 pandas 分块读取并逐块推断类型同一个列在文件前半段是数字、后半段是空值时可能被推断成 object。处理脏数据时干脆用dtypestr全部读成字符串再在转换阶段按需转类型这是常见的可靠做法。2.2 读 Excel 多 Sheet 时 skiprows 与 usecols 的配合Excel 是数据分析里最常碰到的交接格式。一个工作簿里往往有多个 Sheet读取时先用ExcelFile看一眼结构。xls pd.ExcelFile(data_2024.xlsx) print(xls.sheet_names) # 列出所有 Sheet 名 df_sales pd.read_excel( xls, sheet_name销售明细, header0, # 第 0 行是列名 skiprows2, # 跳过文件头部两行说明文字 usecolsA:F, # 只取需要的列减少内存 )sheet_name接受整型索引、Sheet 名或名字列表传列表时返回的是一本字典键是 Sheet 名。skiprows处理前几行是合并单元格标题的常见报表usecols按 Excel 风格列号或列名列表都行。注意header和skiprows是叠加关系先执行skiprows再在剩余数据里定位header两个都填时要按实际文件结构推算。参数作用推荐设置encoding文本编码中文数据优先utf-8-sigdtype指定列类型ID、手机号等一律strparse_dates解析时间列列出参与时间分析的列名skiprows跳过前 N 行非数据行按文件实际头部调整usecols只读指定列大文件必填省内存nrows只读前 N 行先抽样看结构再全量读2.3 从数据库收集数据read_sql 与连接串写法团队数据在 MySQL 或 PostgreSQL 里时常见做法是用 SQLAlchemy 建连接再交给 pandas 的read_sql。这一节的关键原则是不要把整张表拉回来过滤在 SQL 里先做掉。from sqlalchemy import create_engine engine create_engine( mysqlpymysql://user:passlocalhost:3306/sales_db?charsetutf8mb4 ) df pd.read_sql( SELECT 城市, 品类, SUM(金额) AS 销售额 FROM 订单表 WHERE 下单时间 2024-01-01 GROUP BY 城市, 品类 , engine, params{城市: [上海, 杭州]}, )read_sql同时接受 SQL 字符串和表名传表名用read_sql_table更明确。连接串里charset必须和库的实际编码一致否则中文乱码。params做参数化查询避免把变量直接拼进 SQL——拼字符串的写法在数据里出现单引号时会直接报错还有注入风险。数据库侧完成聚合后再进 pandas内存占用和后续处理速度差异很大。2.4 数据读进来先做三项断言数据读进来先做三连检查而不是急着画图assert df.shape[0] 0, 数据为空 assert df[下单时间].isna().sum() 0, 时间列有缺失 assert df[金额].dtype in (float64, int64), 金额列类型不对shape告诉你行数和列数是否符合预期isna().sum()给出每列缺失量的快照dtypes暴露类型推断错误。这三行写完进入转换阶段时心里就有底。收集阶段的边界在于宁可多占一点内存保留原始列也不要因为看着没用提前删列——转换阶段想改口径再找回原数据成本高得多。3. 数据转换用 pandas 完成清洗与特征加工的必调参数转换阶段处理的都是真实数据里必然出现的脏问题缺失、类型错乱、格式混用。这一章给三个最常用的操作面每个都标注参数边界和常见误用。转换的目标不是让脚本跑通而是让每个字段的类型、取值、缺失状态都符合业务约定。3.1 缺失值处理dropna 与 fillna 按列决策# 先看缺失分布再决定策略 missing df.isna().sum() print(missing[missing 0]) # 方案一删行限定在关键列上 df df.dropna(subset[金额, 下单时间], howany) # 方案二填充按列给不同策略 df[会员等级] df[会员等级].fillna(普通) df[金额] df[金额].fillna(df[金额].median())dropna的subset参数限定只在关键列上检查缺失。默认howany会把任何一列缺失的行全删掉不加 subset 时数据量会莫名缩水。fillna的常见误用是对数值列一律填 0——金额列填 0 会制造一批虚假的零销售额后续所有聚合都被污染。用中位数比均值稳健因为均值受极端值影响分类列填普通在业务上说得通但要注意填充值本身会成为分析里的一个类后续建模时保持一致。# 时间序列数据前向填充 df[库存量] df[库存量].ffill()ffill()用前一个有效值填充适合库存、汇率这类没有变动就是沿用上一条的数据。过去老写法fillna(methodffill)在新版 pandas 里已弃用直接写ffill()更干净。这里有个隐藏前提数据必须按时间排过序否则前向填充会把后一个时间点的值抄到前面的空位上。3.2 类型转换字符串、数值与时间的三类坑# 金额列里混入 ¥1,200 这种格式 df[金额] ( df[金额] .astype(str) .str.replace(¥, ) .str.replace(,, ) .astype(float) ) # 时间列统一格式解析 df[日期] pd.to_datetime(df[日期], format%Y-%m-%d, errorscoerce) # 转失败的值变成 NaT单独隔离出来看 bad_dates df[df[日期].isna()]astype(str)先把任何类型统一成字符串再走str访问器做替换这是处理数字里混单位的标准套路。pd.to_datetime的errorscoerce是关键参数解析失败的值变成NaT而不是抛异常中断脚本不至于整体崩掉坏数据也能隔离出来。format显式指定格式比自动推断快也避免2024/01/02和2024-01-02混用时推断错乱。另一个高频清洗是去空格和统一大小写df[品类] df[品类].str.strip().str.lower()strip去首尾空格lower统一小写。手机和 手机 看起来一样groupby 时会被分成两组这类问题不提前清理组织阶段得出的汇总数字全是错的。3.3 用 map、cut 与 apply 做特征加工转换不只是清洗还包括把原始字段变成分析可用的新特征。# map字典映射分类文本转数值标签 df[是否高价值] df[会员等级].map( {金卡: 1, 银卡: 1, 普通: 0} ) # cut连续值分箱 df[金额区间] pd.cut( df[金额], bins[0, 100, 500, 1000, float(inf)], labels[低, 中, 高, 极高], rightTrue, ) # apply 逐行计算大数据集尽量少用 df[客单价] df.apply( lambda r: round(r[金额] / r[件数], 2) if r[件数] 0 else 0, axis1, )map适合字典映射把分类文本转成数值。pd.cut做等宽分箱bins是切分边界labels给每个区间命名rightTrue表示区间左开右闭即 100 这个值会被分到第二个区间。apply带axis1是逐行跑 Python 循环速度最慢几十万行就能感到卡顿能向量化就向量化上面的客单价可以直接写df[金额] / df[件数].replace(0, np.nan)速度快一个量级。操作适用场景常见误用dropna关键列缺失直接删行不加 subset 删掉大量有效行fillna(0)缺失本身有业务语义对金额、销量填 0 制造假数据str.replace清理混入的符号忘记先astype(str)导致报错pd.cut数值分箱边界没考虑等频需求apply(axis1)复杂逐行逻辑大数据集上性能灾难提示inplaceTrue尽量别用。它直接在原对象上修改链式操作时容易触发 SettingWithCopyWarning还难以调试。统一用df df.操作(...)的重新赋值写法排查问题省一半时间。4. 用 pandas 组织数据groupby、透视表与重采样怎么配合组织阶段把清洗好的明细数据聚合成能回答业务问题的视图比如各品类月度销售趋势各城市客单价对比。pandas 里对应三个主力工具groupby、pivot_table、resample。这一章的重点不是罗列函数而是说明三个工具各自解决哪类组织问题、以及它们之间怎么衔接。4.1 groupby 聚合分组键与 agg 的写法# 按城市和品类统计销售额、订单量、客单价 summary ( df.groupby([城市, 品类], as_indexFalse) .agg( 销售额(金额, sum), 订单量(订单号, nunique), 客单价(金额, mean), ) .sort_values(销售额, ascendingFalse) )groupby传入的列表是分组键决定聚合粒度。as_indexFalse让分组键作为普通列保留而不是变成索引后续 join 其他表更顺。agg接收一批新列名(原列名, 聚合函数)的元组这种写法比老的{金额: sum}可读性好也支持同一列做多种聚合——把元组换成列表即可。nunique统计不重复订单号来算订单量比count准确因为count会把同一订单的多行明细都数进去。4.2 pivot_table 与 melt宽表和长表互转透视表的典型场景行是品类列是月份值是销售额。# 宽表行品类列月份 pivot pd.pivot_table( df, index品类, columns月份, values金额, aggfuncsum, fill_value0, ) # 转回长表便于绘图 tidy pivot.reset_index().melt( id_vars品类, var_name月份, value_name销售额, )pivot_table的index是行维度columns是列维度values和aggfunc决定单元格怎么算。fill_value0把没有数据的交叉格填 0否则会留下一大片 NaN。melt是逆透视把宽表压成长表seaborn 和大多数绘图接口偏好长表。注意pivot_table和pivot的区别pivot要求数据里没有重复的(index, columns)组合否则直接抛错pivot_table会自动聚合日常分析里优先用pivot_table。4.3 resample按时间窗口组织数据时间序列数据按周、按月聚合别用 groupby 加月份字符串拼直接用resample。# 时间列转成索引是 resample 的前提 df[下单时间] pd.to_datetime(df[下单时间]) df_ts df.set_index(下单时间) monthly ( df_ts[金额] .resample(ME) # ME 月末旧版写 M .agg([sum, count, mean]) .reset_index() )set_index先把时间列设成索引。频率字符串里ME是月末MS是月初W-MON以每周一为锚点QE是季度末D是自然日。日常九成用ME和W-MON就够。resample后可以接任意聚合函数也能接agg批量算多个统计量。ME出的时间戳是每月最后一天画折线图前想清楚 x 轴标签显示月末还是月初。频率串含义典型用途D自然日日粒度监控W-MON每周一为锚点周报口径ME月末最后一天月度汇总MS月初第一天月度起点对齐QE季度末季报# 环比计算pct_change 的 periods 与频率对齐 monthly[环比] monthly[sum].pct_change(periods1)pct_change的periods要和数据频率对应月数据看同比用 12周数据看周环比用 1。这个计算经常写错因为默认只隔一行。真实业务里还有春节、大促这类外部因素纯看环比数字可能得出错误结论——组织阶段把数据聚合对了解释结论时还需要业务知识兜底。提示groupby 之后只需要一两列结果时先df[[城市, 金额]]选出子集再聚合内存和速度都有改善。5. 从组织好的数据到预测结论Python 回归验证与交付前检查组织好的数据要支撑数据驱动决策就得把某几个因素和结果相关这个判断量化成可验证的结论。完整建模不在这次范围内但有一个必须会的最小验证流程切分数据、拟合线性回归、看误差和残差。5.1 train_test_split 的随机种子是第一个参数from sklearn.model_selection import train_test_split X monthly[[类别A占比, 流量, 价格指数]] y monthly[销售额] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, shuffleTrue )test_size0.3留三成数据做验证random_state42固定随机种子保证每次划分一致。换了种子结果对不上很难判断是数据问题还是划分问题这个参数在调试和协作里都重要。时间序列预测时shuffleTrue是错的会泄露未来信息到训练集此时应shuffleFalse按时间顺序切分。5.2 用线性回归验证特征与目标的关系强度from sklearn.linear_model import LinearRegression from sklearn.metrics import r2_score, mean_absolute_error model LinearRegression() model.fit(X_train, y_train) y_pred model.predict(X_test) print(R2:, r2_score(y_test, y_pred)) print(MAE:, mean_absolute_error(y_test, y_pred)) print(系数:, dict(zip(X.columns, model.coef_)))fit在训练集上学习系数predict在测试集上给出预测。r2_score衡量模型解释了多少方差接近 1 越好mean_absolute_error给出平均误差单位是业务单位比 R2 直观——销售额平均差 8 万老板立刻知道误差量级。model.coef_是每个特征的权重绝对值大说明影响强正负号说明方向。注意这一步验证的是相关性不是因果性系数显著不等于控制变量改变就一定导致目标变化。5.3 交付前的五分钟自检代码结果交给别人之前按固定顺序跑一遍这三段# 1) 数据口径自检行数、日期范围、缺失量 print(df.shape, df[下单时间].min(), df[下单时间].max()) print(df.isna().sum()[df.isna().sum() 0]) # 2) 与上一期数字对比偏差超过 10% 要查原因 current_total monthly[sum].sum() previous_total 1234567 # 替换为上一期已知数字 assert abs(current_total - previous_total) / previous_total 0.1 # 3) 残差散点图看误差是否集中在某个方向 import matplotlib.pyplot as plt residual y_test - y_pred plt.scatter(y_pred, residual, alpha0.5) plt.axhline(0, colorred, linestyle--) plt.xlabel(预测值) plt.ylabel(残差)第三条残差图最容易被跳过残差在预测值大的位置系统性为正或为负说明模型漏掉了某个规律这时候回第 3 章查特征转换而不是继续调模型参数。口径、样本区间、特征列表要写进输出文件的注释头比任何口头说明都可靠。从read_csv开始到这张残差图结束整条链路每一步都是可复现的命令换一台机器重跑得到同一份数字交付才算真正完成。本文还有配套的精品资源点击获取
返回列表