简介:基于Python数据分析与挖掘实战的配套实验资料,涵盖12个章节的完整数据源和源代码demo,面向正在学习数据分析与挖掘的本科生、研究生及相关领域开发者。包内共有701个文件,总大小约334.67MB,以Python源码(.py)、CSV/Excel/txt数据文件、SQL数据库脚本为主,同时包含大量图表图片(jpg/png)、XML配置及部分模型文件,基本覆盖每章实验所需的全部输入与输出。其中py脚本为各实验的可运行示例,csv与xls提供原始数据,sql脚本便于数据入库,图片和模型文件则对应可视化结果与训练产物。资源按章节组织,每个实验目录下均配有对应数据与可运行代码,读者可跟随demo快速还原数据清洗、特征处理、算法建模和结果可视化等流程,也可基于现有数据改造成课程设计或项目案例。目前已有3523人在线学习,适合需要系统对照教材实操、希望获得可直接运行实验代码的数据分析入门者。
1. 为什么我劝你直接拿这套Python数据分析实战实验数据来练手
第一次把《基于Python数据分析与挖掘实战》这套实验资源和源代码压缩包解压出来时,我最直接的反应是:省下了大把找数据的功夫。压缩包里按12个章节分好了对应的数据源和源代码demo,从最基础的数据探索,到后面的客户分群、时序预测,每个实验都配好了可以直接读取的CSV文件。对正在学Python数据分析或数据挖掘的人来说,这套资源真正解决的问题不是“算法原理看不懂”,而是“拿什么数据练、代码怎么跑起来”。
市面上的教程最大的通病是:讲了一堆算法,但配套数据要自己爬、要自己造,字段对不上代码,跑一步报一个错。这套实验包把数据文件和源码demo放在一起,意味着你不需要先当爬虫工程师,就能把精力集中在数据清洗、特征构造和建模调参上。它的定位是拿来复现、拿来练手、拿来改造成自己的分析流程,适合刚从Python基础语法过渡到数据分析与挖掘实战阶段的人。
下面我从文件对照、环境搭建、完整复现、踩坑记录这四个层面,把这份资源完整拆一遍。每一部分都按我自己跑过的步骤来写,参数、报错和改法都放在对应位置。
2. 摸清资源包的家底:七个CSV数据文件与12章实验场景对照
拿到压缩包先别急着跑代码,第一步是搞清楚里面都有什么。这个包里的数据文件看着杂乱,实际上每个CSV对应不同章节的实验场景,弄混了会直接影响后面结果。
2.1 七个CSV文件,分别对应哪类挖掘任务
压缩包解压后,主目录和各章节子目录里一共能看到这几个核心数据文件:huizong.csv、air_data.csv、拓展思考样本数据.csv、moment.csv、catering_sale.csv、data1.csv、data3.csv。其中部分同名文件在多个章节目录下都会出现,属于教材按章节分开存放的正常安排。
| 文件名 | 数据方向 | 常见实验场景 | 关键字段特征 |
|---|---|---|---|
| air_data.csv | 客户画像 | 航空公司客户价值分析、客户分群 | 入会时长、飞行次数、里程、积分兑换 |
| moment.csv | 行为序列 | 用户行为分析与事件识别 | 时间戳、用户标识、行为类型、对象编号 |
| catering_sale.csv | 销量预测 | 餐饮菜品销量预测、时序分析 | 日期、销量两列为主 |
| huizong.csv | 汇总数据 | 回归分析、影响因素分析 | 多列数值特征加目标列 |
| 拓展思考样本数据.csv | 扩展练习 | 分类或聚类练习 | 字段随机,结构不固定 |
| data1.csv、data3.csv | 章节配套 | 各自对应章节的输入数据 | 宽表或长表,具体看源码 |
air_data.csv 是这里面最值得先跑的一个文件,它记录的是航空公司的客户基本信息和消费行为,字段包括入会时间、飞行公里数、累计积分、积分兑换次数等。这种数据天然适合做客户价值分群——也就是业界常说的RFM模型落地场景。catering_sale.csv 则很典型,日期加销量的结构,是时间序列预测的标准输入。moment.csv 的结构比较特殊,每一行都是某个用户在某个时间点产生的行为,做事件识别和序列分析时用它。huizong.csv 是一个已经汇总过的宽表,适合跑回归类实验。
2.2 从文件名到建模目标:算法为什么这样选
明确了数据文件对应的实验方向之后,再看源码里为什么要用那些算法。air_data.csv 对应的是客户分群问题,数据没有标签,属于典型的无监督学习场景。教材和大部分开源做法选择 K-Means 聚类,原因很直接:客户价值分群不要求极高的精度,而要求结果可解释,K-Means 跑出来的每一类客户都能通过R、F、M三个维度的均值去描述业务含义。moment.csv 对应的是行为事件识别,数据是用户行为序列,传统的逻辑回归处理不了这种带时间顺序的输入,所以相关章节的源码会选用神经网络或循环网络来建模。catering_sale.csv 是单变量时间序列,ARIMA 或回归模型是常见选型,先做平稳性检验再做差分,是这套流程里绕不开的一步。
选型这块看多了会发现规律:没有标签看聚类,有序列看时序,有行为序列看神经网络。这套资源里的源码demo基本都沿着这条主线走,所以复现完一个案例,其他章节的代码读起来也不会太费劲。
2.3 这套资源的边界:能练什么,不能当什么
必须说清楚一个边界。这套实验数据是经过加工处理的“干净”数据,它适合验证算法流程、练习代码能力,但它不是真实生产环境里的原始日志。比如 air_data.csv 里的字段已经做过脱敏和整理,不会出现彻底无法解析的脏数据;moment.csv 里的行为类型也被枚举化过了,跟实际业务系统直接导出的日志结构有明显差异。拿它学数据分析与挖掘的流程没问题,但不要指望把这套数据直接搬到公司项目里做成品。复现的价值在于把流程走通,在于知道每一步该看什么、该调什么,这也是我后面几章要展开的重点。
3. 把环境跑起来:conda依赖安装与第一个demo验证
不管看代码还是改代码,环境先跑通是第一优先级。这套资源是围绕《Python数据分析与挖掘实战》教材组织的,源码里依赖的库比较集中,但版本敏感,不能一把梭装最新版。
3.1 依赖清单:版本别一把梭最新
解压源码后扫一遍 import 语句,常用的依赖基本就是 pandas、numpy、scikit-learn、matplotlib、statsmodels,涉及神经网络的章节还会用到 keras 和 tensorflow。为了不踩新版API改名的坑,我在自己机器上固定了一套经过验证的版本组合:
| 库 | 版本 | 用途 |
|---|---|---|
| python | 3.8 | 兼容性最好,keras 2.x 和 sklearn 1.2 都能稳定跑 |
| pandas | 1.5.3 | 数据读取、清洗、聚合 |
| numpy | 1.24.3 | 数值计算 |
| scikit-learn | 1.2.2 | 聚类、回归、预处理、模型评估 |
| matplotlib | 3.7.2 | 可视化,中文显示需单独配置 |
| statsmodels | 0.14.0 | 时间序列、平稳性检验 |
| keras | 2.12.0 | 神经网络相关章节 |
| tensorflow | 2.12.0 | keras 后端 |
固定版本而不是追最新,是因为新版 scikit-learn 1.4 之后移除了部分老接口,numpy 2.x 也和旧版 pandas 存在兼容性冲突。教材源码本身又不是每年跟着API走的,用太新的版本反而会让 demo 跑不起来。python 3.8 是这套依赖组合里最省心的选择,既能装 tensorflow 2.12,又不会被新版语法限制。
3.2 用conda创建独立环境并安装依赖
我不建议直接在 base 环境里装这些包,一是污染全局环境,二是不同项目之间版本容易互相顶掉。用 conda 单独建一个环境是最稳妥的做法,操作如下:
conda create -n dm_lab python=3.8 conda activate dm_lab pip install pandas==1.5.3 numpy==1.24.3 scikit-learn==1.2.2 matplotlib==3.7.2 statsmodels==0.14.0 keras==2.12.0 tensorflow==2.12.0第一行创建名为 dm_lab 的环境并指定 python 3.8,第二行激活环境,后面几行用 pip 安装固定版本的依赖。用 pip 而不是 conda 装这些库,是为了避免 conda 在解析依赖时把某个库悄悄升到最新版。固定版本号的意义在于可复现:今天装完能跑,三个月后重装一次,结果仍然一致。
装完后建议顺手把 jupyter 也装上,因为这套源码里有一部分demo是写在 notebook 里的,缺了它没法直接打开:
pip install jupyter3.3 验证环境:先跑通读取demo再开干
环境装完不要直接去跑整章代码,先做一次最小验证,确认 import 和文件读取都正常:
python -c "import pandas, numpy, sklearn, matplotlib; print(pandas.__version__, sklearn.__version__)"如果这行命令能正常输出版本号,说明核心依赖装好了。接下来找一个数据文件做读取测试,这里以 air_data.csv 为例:
python -c "import pandas as pd; df = pd.read_csv('air_data.csv'); print(df.shape); print(df.head(3))"输出应该能看到一个几万行、二十列左右的 DataFrame,并且 head 打印的前三行字段有明确的业务含义。如果这一步报 UnicodeDecodeError,说明文件编码不是 utf-8,后面会用 gbk 方式重新读取;如果报 FileNotFoundError,说明你的命令执行目录不在数据文件所在目录。这两个报错是整套资源里出现频率最高的问题,第5章我会专门展开。
4. 复现客户分群实验:从读air_data.csv到K-Means聚类出结果
环境通了之后,我建议第一个复现的案例选 air_data.csv 对应的客户价值分析。这个案例链路完整,从数据探索、数据清洗到特征构造和建模都有涉及,跑完一遍,其他章节的代码套路基本就能摸清。
4.1 数据探索:先看字段、类型和缺失率
不要一上来就跑模型,先看清数据长什么样。我一般先执行三件事:看字段类型、看数值分布、看缺失率。
import pandas as pd df = pd.read_csv('air_data.csv', encoding='utf-8') print(df.info()) # 关键数值字段的分布 print(df.describe()) # 缺失值占比,只展示有缺失的字段 missing_rate = df.isnull().mean() print(missing_rate[missing_rate > 0])df.info() 用来确认每个字段的数据类型,数值类型和对象类型在处理方式上完全不同。df.describe() 能快速发现异常值,比如某个字段最大值是 0,或者最小值和最大值相差几百倍,这些都是后面清洗要处理的点。df.isnull().mean() 是算缺失率最快的写法,返回的是每个字段缺失值占总体比例,大于 0 的字段才是真正需要决策的。
这套书里的实验数据虽然经过加工,但不是完全干净的。air_data.csv 里有一个典型问题:部分客户的累计积分、飞行公里数同时为 0,这类“未激活”客户对聚类效果有干扰,直接放进模型会把分类边界拉偏。
4.2 数据清洗与RFM特征构造
清洗思路是先把异常样本删掉,再把原始字段压缩成RFM三个业务维度。R 表示最后一次入会距今的时长,F 表示飞行频率,M 表示总里程,这是客户价值分析里最经典的三个特征。
# 剔除积分和里程同时为0的客户,这类样本不是目标客群 mask = (df['SUM_YR_1'] != 0) & (df['SUM_YR_2'] != 0) df_clean = df[mask].copy() # 构造RFM三个维度,字段名以实际数据为准 df_rfm = pd.DataFrame({ 'R': df_clean['LAST_TO_END'], # 最后一次乘机距离观测窗口结束的时间 'F': df_clean['FLIGHT_COUNT'], # 观测窗口内的飞行次数 'M': df_clean['SEG_KM_SUM'] # 观测窗口内的总飞行公里数 }) print(df_rfm.describe())这里用 SEG_KM_SUM 代表 M 是常见做法,因为在没有真实票价字段的情况下,里程是最能反映消费能力的替代指标。数据清洗这一步的逻辑是:聚类算法不区分业务含义,你喂进去的是垃圾,它分出来的群就只能是垃圾。把全零样本剔除,是为了避免模型学出“什么都没做”的客户群。
4.3 标准化与K-Means聚类
RFM 三个维度量纲差别很大,直接聚类会让飞行公里数一个字段主导整个距离计算。所以必须先标准化,再聚类:
from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans # z-score标准化,注意要fit_transform得到的是ndarray,不是DataFrame X = StandardScaler().fit_transform(df_rfm) # 教材取5类客户,n_init=10避免局部最优,random_state固定结果可复现 model = KMeans(n_clusters=5, n_init=10, random_state=42) labels = model.fit_predict(X) df_rfm['cluster'] = labels print(df_rfm.groupby('cluster').mean())StandardScaler 把每个维度变成均值0、方差1的分布,这样计算欧氏距离时三个维度权重相等。n_clusters=5 不是拍脑袋定的,教材里对应的是五类客户价值分级:高价值、中价值、低价值、潜力型、流失型。n_init=10 表示K-Means会跑10次初始中心选择,取其中最优结果,避免因为随机初始化选中坏点。random_state=42 纯粹是为了让运行结果可复现,你可以改成任何整数,只要固定就行。
跑完 groupby 之后,需要人工观察每一类客户在R、F、M三个维度上的均值。比如某类客户的 R 很大但 F 和 M 都很小,说明这群人已经很久没飞了,属于需要唤醒的流失倾向客户;另一类 R 小、F 大、M 大,就是高价值群体。聚类算法只负责分组,业务解读必须自己做。
4.4 同一套流程在catering_sale上的变化
客户分群跑通之后,可以试着把同样的流程套到 catering_sale.csv 上看变化。这个文件不是聚类场景,而是销量预测,所以流程要从“清洗+标准化+聚类”换成“平稳性检验+差分+ARIMA”。
df_sale = pd.read_csv('catering_sale.csv', encoding='gbk', engine='python') print(df_sale.head())读取时用 gbk 编码是因为这个文件和 air_data.csv 的编码格式不一样,直接用 utf-8 会报错。换成销量预测后,核心动作变成了画时序折线图、做 ADF 平稳性检验、按需做一阶差分。同一个资源包,不同数据文件对应的处理链路完全不同,这正好是练手的意义所在。
5. 避坑与常见问题:复现这套资源的五个翻车点
我前前后后帮人排查过不少次这套资源的运行问题,归纳下来高频报错集中在下面五个点。每一条都按“现象→原因→解决”的顺序写清楚。
5.1 中文乱码与UnicodeDecodeError:同一包里编码不统一
现象:pd.read_csv('catering_sale.csv') 直接抛 UnicodeDecodeError,提示 utf-8 codec 无法解码;强行跳过报错读进来,中文列名全是乱码。
原因:这套压缩包里的CSV编码并不统一。air_data.csv 是 utf-8,catering_sale.csv 是 gbk。pandas 默认用 utf-8 打开所有文件,遇到 gbk 编码自然翻车。
解决:读取前先试编码,报错后改用 gbk 并指定 engine:
df_sale = pd.read_csv('catering_sale.csv', encoding='gbk', engine='python')engine='python' 是告诉 pandas 用纯 Python 解析器而不是 C 解析器,对编码兼容性更好。判断文件编码的笨办法是用记事本打开CSV看中文是否正常,正常的就是 gbk,乱码的就是 utf-8。
5.2 FileNotFoundError:相对路径的坑
现象:源码文件和数据文件明明在同一个文件夹里,运行代码却报 FileNotFoundError,说找不到 air_data.csv。
原因:绝大多数情况是当前工作目录不对。在 Jupyter 里跑代码,工作目录默认是 notebook 所在的目录;在 PyCharm 里跑,工作目录可能会被设置为项目根目录。源码里写的是相对路径 'air_data.csv',实际寻找路径和你以为的路径不是同一个。
解决:在代码开头显式切换工作目录到数据所在位置,或直接用绝对路径拼接:
import os # 脚本所在目录,而不是当前执行目录 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) df = pd.read_csv(os.path.join(BASE_DIR, 'air_data.csv'), encoding='utf-8')在 Jupyter 里没有file,可以用 os.getcwd() 先打印当前目录,再决定要不要 os.chdir() 切过去。这个坑不解决,后面每换一个章节的代码都要重新报一次错。
5.3 matplotlib中文标题变方框
现象:画出来的折线图、散点图上面的中文标题和图例全是小方块,英文正常。
原因:matplotlib 默认字体里没有中文字符,系统里装了中文字体它也不认,需要手动指定。
解决:全局设置字体和负号显示:
import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows用黑体,macOS可用Arial Unicode MS plt.rcParams['axes.unicode_minus'] = False # 修复负号显示成方块的问题axes.unicode_minus 这个参数很多人会漏,设了中文字体后负号还是会变方块,必须一起配上。
5.4 sklearn版本差异:老代码跑不了新版API
现象:源码里某些代码在 sklearn 1.2 上直接报 AttributeError,比如找不到 Imputer、某些参数名不识别。
原因:教材源码写作时间较早,部分代码基于 sklearn 0.19 的旧API。sklearn 1.0 之后移除了 preprocessing.Imputer,把填充缺失值归到了 impute 模块下;一些分类器的参数也改了名字或加了限制。
解决:两个选择。第一个是在 3.2 步的环境里固定安装 sklearn 1.2.2,这个版本能兼容绝大多数老代码。第二个是遇到报错时手动改API调用:
# 旧写法,新版已移除 # from sklearn.preprocessing import Imputer # 新写法 from sklearn.impute import SimpleImputer imputer = SimpleImputer(strategy='mean')碰到报错就搜报错信息里的模块名,优先看它是不是 sklearn 内部模块调整导致的。
5.5 同名CSV文件容易拿错
现象:复现结果和教材上的图、表对不上,数据行数和字段都对,但聚类中心数值差很多。
原因:压缩包里 huizong.csv、moment.csv、data1.csv 这些名字在多个章节子目录下都存在。用资源管理器直接搜索文件名,很容易搜到另一个章节的同名文件。文件名一样,内容可能完全不同,拿错文件跑出来的结果自然莫名其妙。
解决:不要全盘搜索文件,直接从对应章节的子目录进入,配合源码里的相对路径运行。运行前先打印 df.shape 和 df.head(),确认数据规模和你预期一致再继续。这一步花不了十秒钟,能省掉几小时的无效排查。
6. 从跑通到改造:验证聚类效果和迁移到你自己的CSV
资源和源代码跑通只是第一步。做完第4章的客户分群案例后,我建议你做三个小改造,它们分别对应验证、迁移、对比,做完对这套流程的掌控度会明显不一样。
6.1 用轮廓系数验证聚类不是黑匣子
K-Means 输出五类标签后,怎么判断分群合理?靠肉眼不可靠,靠轮廓系数是标准做法:
from sklearn.metrics import silhouette_score score = silhouette_score(X, labels) print('silhouette_score:', score) # 配合PCA降维到2维做可视化 from sklearn.decomposition import PCA import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False pca = PCA(n_components=2, random_state=42) X_pca = pca.fit_transform(X) plt.scatter(X_pca[:, 0], X_pca[:, 1], c=labels, cmap='viridis', s=8) plt.title('K-Means 聚类结果(PCA投影)') plt.show()轮廓系数取值范围在 -1 到 1 之间,大于 0.4 说明聚类效果可接受,低于 0.2 基本说明聚类簇之间没有拉开。PCA 投影只是工具,它把高维空间压到二维方便观察,聚类本身是在原始标准化空间里计算的。
6.2 换成你自己的数据:只改字段映射
把案例迁移到自己业务数据上的关键,是看懂原始的RFM构造代码,然后把你自己的字段替换进去:
# 假设你自己的数据包含这三个字段 df_rfm = pd.DataFrame({ 'R': df_clean['last_visit_days'], # 距离最近一次访问的天数 'F': df_clean['order_count'], # 订单数量 'M': df_clean['total_amount'] # 消费金额 })字段名直接从你自己的 DataFrame 里复制过来,不要手敲。替换完先打印 describe() 确认没有全零列,再继续标准化和聚类。如果你的数据里字段语义和R/F/M对不上,就不要硬套RFM,直接用原始字段聚类也是一种做法,只是业务解读要自己做。
6.3 尝试把z-score换成min-max,观察结果变化
最后一个值得做的小改动改在标准化这一步:
from sklearn.preprocessing import MinMaxScaler X_mm = MinMaxScaler().fit_transform(df_rfm) model_mm = KMeans(n_clusters=5, n_init=10, random_state=42) labels_mm = model_mm.fit_predict(X_mm)对比两次聚类中心和各簇样本数,你会发现分群结果有明显差异。这没有绝对的对错,只是两种标准化对异常值敏感度不同:z-score 受极端值影响更大,min-max 会把数据压到 0-1 区间内保留原始分布形态。理解了这一点,你对数据预处理的理解就不再是单纯“套函数”,而是知道它在模型中真实影响是什么。
从那以后,我复现每套实验数据都强制自己走一遍规定动作:先 df.info() 看字段,再 isnull().mean() 看缺失率,最后打印 df.shape 确认数据规模,然后才开始建模。这套资源我前后跑过几遍,最深的体会是大部分“跑不出来”都不是算法问题,而是环境和数据路径问题。希望这篇拆解能帮你把每个章节的代码都顺利跑通,再花点时间把案例改成自己的数据,收获会更大。
本文还有配套的精品资源,点击获取