ARTICLE DETAIL

资讯详情

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

Python校园消费行为分析实战:从数据清洗到聚类建模全链路

Python校园消费行为分析实战:从数据清洗到聚类建模全链路 简介这是一份面向数据分析初学者与高校学生的Python实战项目资源围绕校园消费行为分析展开可用于课程设计、技能练习或研究参考。压缩包共20个文件约20.37MB包含4个py源码脚本、4个csv数据文件、9张png与3张jpg结果图分别对应分析代码、原始消费数据与可视化输出结构清晰便于按任务模块对照学习。项目覆盖数据采集、清洗处理、分析与可视化、消费行为模型构建及结果展示等完整流程读者可借助源码与数据复现聚类分析、关联规则和预测模型等典型方法理解从原始数据到结论报告的落地路径。目前已有794人学习下载适合希望掌握Python数据处理与分析技术、积累消费行为建模经验的人群参考使用。1. 从一份校园消费数据包说起Python 分析链路到底能跑出什么很多做校园信息化或者零售运营的朋友手里其实不缺数据缺的是一条能跑通、能复现、能拿给别人看的分析链路。这份「基于 Python 的学生校园消费行为分析」资源包恰好就是一条完整链路的实物切片data目录下放着data1.csv、data2.csv两份原始消费流水code目录里是task1_X1.py到task3_X4.py这一组任务脚本result目录则沉淀了task1_X.csv、task1_1_X.csv两个中间结果表和十来张task2_X*.png、task3_X*.png可视化图。它解决的不是「教你怎么装 Python」这种入门问题而是把采集、清洗、聚合、可视化、建模这条链路上每一步的输入输出都摆出来让你能对着结果反推代码逻辑。适合谁适合已经会写基础 Python、想拿一份真实校园消费数据练手的数据分析初学者也适合需要给学校后勤或校园商家做消费洞察报告、但不想从零造轮子的从业者。下面我按「资源是什么 → 怎么跑 → 坑在哪 → 怎么进阶」的顺序拆一遍。2. 拆包与数据摸底两份 CSV 和一组任务脚本怎么对上2.1 目录结构与文件职责拿到压缩包先别急着跑代码先把目录摊开看一遍。这份资源的文件组织是典型的「数据 / 代码 / 结果」三分法职责边界很清楚目录文件作用datadata1.csv、data2.csv原始消费流水两份文件大概率是不同维度或不同时间段的记录codetask1_X1.py、task1_X2.py、task2_X1.py、task3_X1.py等按任务编号组织的分析脚本task1 偏清洗、task2 偏统计可视化、task3 偏建模resulttask1_X.csv、task1_1_X.csv清洗或聚合后的中间结果表可直接用 Excel 打开核对resulttask2_X1.png~task2_X5.png、task3_X1.png~task3_X4.png各任务输出的图表是验证代码是否跑对的直接依据demo.jpg在根目录和子目录都出现通常是运行效果截图或流程图用来对照「跑完应该长什么样」。这里有个细节值得注意脚本命名里的X1、X2、X4不是随便编的它对应的是同一任务下的不同子问题或不同数据集分支比如task3_X1.py和task3_X2.py可能分别对data1和data2做聚类。跑之前先确认每个脚本读的是哪份 CSV否则很容易出现「代码没报错但结果对不上」的玄学问题。2.2 用 pandas 做第一轮数据摸底在跑任何分析脚本之前我习惯先用一段独立的摸底代码把两份 CSV 的字段、类型、缺失情况看清楚。这一步能帮你判断后面脚本里的列名引用是否和实际数据一致import pandas as pd # 分别读取两份原始数据注意编码校园系统导出的 CSV 常见 gbk 或 utf-8-sig for name in [data1.csv, data2.csv]: df pd.read_csv(fdata/{name}, encodingutf-8-sig) print(f {name} ) print(形状:, df.shape) print(字段:, list(df.columns)) print(前 3 行:\n, df.head(3)) print(缺失值:\n, df.isnull().sum()) print(类型:\n, df.dtypes)这段代码的逻辑很直接循环读两份文件先看形状判断数据量级再看字段名确认后面脚本引用的列是否存在最后看缺失值和类型。参数上唯一需要留意的是encoding如果报UnicodeDecodeError把utf-8-sig换成gbk再试这是国内校园系统导出 CSV 最常见的两种编码。跑完这一步你会得到两份数据的字段清单拿它去对照task1_X1.py里的列名能提前发现「脚本里写的是amount但数据里叫money」这类低级但致命的错位。2.3 任务脚本的执行顺序这份资源的脚本是按 task 编号递进的不要跳着跑。合理的执行顺序是先跑task1_X1.py和task1_X2.py完成清洗产出result/task1_X.csv和task1_1_X.csv再跑task2_X1.py到task2_X5.py做统计和可视化产出那批task2_*.png最后跑task3_X1.py到task3_X4.py做建模产出task3_*.png。每个脚本跑完先去result目录确认对应的输出文件是否生成、时间戳是否更新再跑下一个。这种「跑一个验一个」的节奏比一口气全跑完再排查要省事得多。3. 清洗与聚合task1 脚本里的字段处理和中间结果核对3.1 消费流水的典型清洗动作校园消费数据常见的脏法就那么几种金额字段带货币符号、时间字段格式不统一、有退款导致的负数、有重复刷卡记录。task1_X1.py和task1_X2.py干的就是把这些收拾干净。我一般会在读懂原脚本后按下面这个模式补一段可复用的清洗逻辑方便你对照理解每一步在干什么import pandas as pd df pd.read_csv(data/data1.csv, encodingutf-8-sig) # 1. 金额列去掉可能的货币符号并转 float df[amount] df[amount].astype(str).str.replace(, , regexFalse) df[amount] pd.to_numeric(df[amount], errorscoerce) # 2. 时间列统一转 datetime无法解析的置为 NaT df[trade_time] pd.to_datetime(df[trade_time], errorscoerce) # 3. 剔除金额为空或为负的异常记录退款单独处理 df df[df[amount].notna() (df[amount] 0)] # 4. 按「学号 时间 金额」去重防止重复刷卡 df df.drop_duplicates(subset[stu_id, trade_time, amount]) # 5. 导出中间结果供 task2 使用 df.to_csv(result/task1_X.csv, indexFalse, encodingutf-8-sig) print(清洗后行数:, len(df))逻辑说明第 1 步处理金额字段的类型污染errorscoerce保证无法转换的值变成NaN而不是直接抛异常第 2 步统一时间格式这是后面做「按小时/按天聚合」的前提第 3 步把退款和异常金额剔掉注意如果你的分析目标包含退款行为这一步要改成单独标记而不是删除第 4 步的去重键是经验值校园一卡通重复刷卡的判定通常就是这三要素相同。参数上encoding和前面摸底保持一致导出时用utf-8-sig是为了 Excel 打开不乱码。3.2 中间结果表的核对方法result/task1_X.csv和task1_1_X.csv是清洗后的产物也是 task2 的输入。核对这两个文件重点看三件事行数是否比原始数据少少了说明清洗生效、字段是否比原始数据多多了说明做了衍生比如拆出了「小时」「星期几」、金额列的分布是否合理有没有离谱的极大值。我一般会写一段快速核对代码import pandas as pd raw pd.read_csv(data/data1.csv, encodingutf-8-sig) clean pd.read_csv(result/task1_X.csv, encodingutf-8-sig) print(原始行数:, len(raw), 清洗后行数:, len(clean)) print(清洗后字段:, list(clean.columns)) print(金额描述统计:\n, clean[amount].describe())如果清洗后行数只少了个位数说明数据本身比较干净如果少了一半以上就要回头检查去重键是不是设得太宽把正常记录也误删了。金额的describe()里重点看max如果出现几万甚至几十万的单笔消费基本可以判定是异常值需要在清洗阶段加一个分位数截断。3.3 衍生字段的构造消费行为分析里光有原始时间和金额是不够的task2 的很多图表依赖衍生字段。常见的衍生包括从trade_time拆出hour几点消费、weekday周几消费、is_weekend是否周末以及按金额分档的amount_level低/中/高消费。这些字段一般在 task1 阶段就构造好写进中间结果表task2 直接拿来用。构造时注意hour要用dt.hourweekday用dt.dayofweek周一是 0别用dt.weekday搞混。这一步没有太多坑但字段名要和 task2 脚本里的引用严格一致否则又是一轮「跑得通但图是空的」。4. 可视化与建模task2、task3 脚本的图表逻辑和模型选择4.1 task2 的五张图分别在回答什么问题task2_X1.png到task2_X5.png这五张图基本覆盖了消费行为分析的标准问题集消费金额分布、消费时间分布、不同人群消费对比、消费频次统计、消费趋势变化。对应的脚本task2_X1.py到task2_X5.py通常用 matplotlib 或 seaborn 出图。我拿「按小时统计消费笔数」这个最常见的图举例说明脚本里的逻辑import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(result/task1_X.csv, encodingutf-8-sig) df[trade_time] pd.to_datetime(df[trade_time]) df[hour] df[trade_time].dt.hour hourly df.groupby(hour)[amount].agg([count, sum]).reset_index() plt.figure(figsize(10, 5)) plt.bar(hourly[hour], hourly[count], color#4C72B0) plt.xlabel(小时) plt.ylabel(消费笔数) plt.title(校园消费时段分布) plt.xticks(range(0, 24)) plt.tight_layout() plt.savefig(result/task2_X1.png, dpi150)逻辑说明先按小时分组同时统计笔数和金额agg([count, sum])一次拿到两个指标画图时用柱状图看分布形态xticks固定 0 到 23 保证横轴完整。参数上dpi150是出图清晰度和文件大小的平衡点tight_layout防止标签被裁。跑完对照result/task2_X1.png如果横轴只有部分小时、或者柱子高度明显异常回去检查hour字段是否构造正确、有没有把NaT混进去。4.2 task3 的建模脚本在做什么task3_X1.py到task3_X4.py对应的是消费行为建模从摘要描述看涉及聚类分析、关联规则和预测模型。聚类比如 KMeans 对学生按消费金额和频次分群是最常见的入口关联规则比如「买了 A 的人也会买 B」适合食堂窗口或超市商品分析预测模型比如预测下月消费额则依赖时间序列或回归。以聚类为例脚本的核心逻辑通常是选特征 → 标准化 → 定 K 值 → 聚类 → 可视化。这里有个选型理由要讲清楚消费金额和消费频次量纲差很多不标准化直接聚类结果会被金额主导频次几乎不起作用。所以StandardScaler这一步不能省。import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.cluster import KMeans df pd.read_csv(result/task1_X.csv, encodingutf-8-sig) # 按学生聚合出消费总额和消费笔数两个特征 stu df.groupby(stu_id)[amount].agg([sum, count]).reset_index() stu.columns [stu_id, total_amount, trade_count] # 标准化消除量纲差异 X StandardScaler().fit_transform(stu[[total_amount, trade_count]]) # 聚成 3 类随机种子固定保证可复现 km KMeans(n_clusters3, random_state42, n_init10) stu[cluster] km.fit_predict(X) stu.to_csv(result/task3_X1.csv, indexFalse, encodingutf-8-sig) print(stu.groupby(cluster)[[total_amount, trade_count]].mean())逻辑说明先按学号聚合出两个核心特征再标准化再聚类。n_clusters3是常见起点实际 K 值要靠肘部法或轮廓系数确定脚本里如果写死了 3你可以改成循环试 2 到 6 看效果。random_state42和n_init10是为了结果可复现这两个参数不设的话每次跑出来的分群可能不一样做报告时会很尴尬。跑完看每个簇的均值如果某一簇的total_amount和trade_count都明显偏高那就是「高消费高频」人群对应的是校园里消费能力最强的那批学生。4.3 结果集与图表的交叉验证result目录里的 PNG 和 CSV 是互相印证的CSV 是数值结果PNG 是数值的视觉呈现。验证时不要只看图好不好看要拿图去反推数值是否合理。比如聚类图里如果三个簇的点完全重叠说明特征区分度不够或者没标准化时间分布图里如果凌晨时段也有大量消费要么数据有问题要么就是把NaT错误地归到了 0 点。这种交叉验证的习惯能帮你在写报告之前就把数据问题拦下来。5. 避坑与排查跑这份资源时最容易翻车的五个地方5.1 编码不对导致读取直接报错现象pd.read_csv抛UnicodeDecodeError脚本第一步就挂。原因国内校园系统导出的 CSV 常用gbk或gb2312而脚本里可能写的是默认utf-8。解决先试utf-8-sig不行换gbk再不行用chardet探测。我一般会在读取处加一个 try 链把两种编码都兜住。5.2 列名对不上导致 KeyError现象脚本跑到df[amount]时报KeyError: amount。原因实际 CSV 的列名可能是中文「消费金额」或者英文money和脚本里的引用不一致。解决先跑第 2 章的摸底代码打印df.columns拿实际列名去改脚本或者统一在读取后做一次df.rename(columns{...})映射。这个坑血泪经验最多因为报错信息只告诉你缺哪个键不告诉你实际有哪些键。5.3 时间字段解析失败被静默丢弃现象清洗后行数骤减但没有任何报错。原因pd.to_datetime(..., errorscoerce)会把解析失败的值变成NaT如果后面又做了dropna这些行就被无声无息地删了。解决在to_datetime之后先统计NaT数量如果占比超过 5%说明时间格式比预想的复杂需要先用字符串切片或正则把格式统一再转。别让coerce成为黑匣子。5.4 聚类不标准化导致分群失真现象聚类结果里某一簇几乎包含所有样本另外两簇只有零星几个点。原因特征量纲差异大金额的方差远大于频次KMeans 的距离计算被金额主导。解决聚类前必须StandardScaler或者改用对量纲不敏感的方法。判断是否标准化到位可以看标准化后各特征的均值是否接近 0、标准差是否接近 1。5.5 图表中文显示成方块现象PNG 里中文标题和标签全是方框。原因matplotlib 默认字体不含中文。解决在绘图脚本开头设置plt.rcParams[font.sans-serif] [SimHei]和plt.rcParams[axes.unicode_minus] False。如果系统没有 SimHei换成Microsoft YaHei或WenQuanYi Micro Hei。这个坑不影响数值结果但会让你的结果图没法直接放进报告属于「不致命但很烦」的那类。6. 进阶玩法把这份资源改成可复用的分析模板跑通原脚本只是第一步真正让这份资源产生长期价值的方式是把它改造成一个参数化的分析模板。我的做法是抽出一个config.py把文件路径、编码、聚类 K 值、图表输出目录这些易变项集中管理脚本里只引用配置不再写死。这样换一份新的校园消费数据只需要改配置里的路径和字段映射整条链路就能复用。具体来说我会在config.py里定义# config.py DATA_DIR data RESULT_DIR result ENCODING utf-8-sig COL_MAP {消费金额: amount, 交易时间: trade_time, 学号: stu_id} K_CLUSTERS 3 RANDOM_STATE 42然后在每个 task 脚本开头from config import *读取时统一走pd.read_csv(f{DATA_DIR}/data1.csv, encodingENCODING).rename(columnsCOL_MAP)。这样列名映射只维护一处换数据时改COL_MAP就行不用去每个脚本里搜替换。K 值和随机种子也集中管理做对比实验时改一个地方就能重跑全链路。再进一步可以把 task1 到 task3 串成一个run_all.py用subprocess或直接函数调用的方式按顺序执行每步之间加一个输出文件存在性检查任何一步失败就中止并打印是哪一步、缺哪个文件。这样你交付给别人的就不是一堆散脚本而是一条能一键跑通、失败能定位的流水线。验证模板是否改造成功标准很简单拿一份字段名不同的新 CSV只改config.py里的COL_MAP和路径全链路能跑出结果图就算成了。从那以后我每次拿到这种「源码 数据 结果集」的资源包都强制先跑一遍摸底、再核对中间结果、最后才动建模脚本绝不跳步。这套顺序帮我省下了大量「跑得通但结果不对」的排查时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表