ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

一个月学会数据分析:从数据清洗到可视化项目实战

一个月学会数据分析:从数据清洗到可视化项目实战 数据分析这条学习路线之所以劝退很多人并不是因为 Python 或 pandas 真的难到学不会而是大多数入门材料把数据清洗、数据分析、数据挖掘和数据可视化拆成了四个互不相干的碎片学完每一块之后仍然不知道如何串成完整链路。2026 年的招聘环境里企业更看重候选人能否直接处理脏数据、产出可解释的结论而不是只背 API。一个月时间安排得当从零基础到独立完成 2 到 3 个数据清洗、分析和可视化项目是完全可以做到的。这篇文章把一个月拆成四个阶段每个阶段都有可运行的代码、常见报错和工程落地的注意事项帮助你建立一条从原始数据到业务结论的完整主线。1. 先理解一个月学数据分析到底在学什么1.1 数据清洗、分析、挖掘和可视化从来不是四门独立的课很多人学习顺序错了先学 Python 语法再学 matplotlib 画图最后才开始碰 pandas结果画图时会了等到清洗真实数据时又全忘了。实际工作中这四件事是反复穿插的数据清洗把缺失、重复、异常、类型不对的数据改造成能参与计算的结构化数据。数据分析通过统计指标、分组对比和趋势判断回答“发生了什么”。数据挖掘在分析基础上进一步找规律比如用户分层、影响因素、关联规则或简单预测。数据可视化把分析结论用图表呈现出来让非技术人员也能看懂。这四步不是串行执行一次就结束。可视化之后发现了异常往往要回到清洗阶段重新处理数据挖掘出了新维度又要重新做分组统计。所以一个月内要建立的不是四个孤立技能而是一个能来回迭代的工作流。1.2 一个月四阶段时间线和验收标准以全职每天投入 5 到 6 小时计算一个月大约有 150 到 180 小时有效学习时间。零基础学完这些内容核心不是“看完视频”而是每学一个知识点都能运行出结果。阶段时间学习内容验收标准第一阶段第 1 周Python 基础、Jupyter、NumPy、pandas 数据结构能读取 CSV、Excel完成 DataFrame 的增删改查第二阶段第 2 周pandas 进阶、数据清洗、SQL 基础能独立完成一张表的去重、补缺失、改类型、筛异常第三阶段第 3 周描述统计、分组聚合、相关分析、matplotlib 和 seaborn能算指标并用 3 种以上图表表达结论第四阶段第 4 周数据挖掘入门、RFM 分层、2 到 3 个完整项目能写一个从清洗到可视化报告的脚本并输出结论每个阶段结束都要留下产物第 1 周是 notebook 练习第 2 周是一份清洗后的干净数据第 3 周是图表第 4 周是项目代码和报告。没有产物的学习到第 30 天基本等于没学。1.3 零基础真正需要补的前置知识零基础不是指完全不会打字而是指没有接触过编程和数据库。这部分人最需要补的只有三样Python 基础语法变量、列表、字典、函数、循环、条件判断够用即可不需要深入到面向对象。文件概念知道 CSV、Excel 是什么知道一行是记录、一列是字段。简单数学直觉平均数、百分比、排序、最大值最小值这些高中水平的知识就够完成入门项目。不需要先学完一整本 Python 教材再开始数据分析。正确做法是先学 2 到 3 天基础语法然后立刻进入 pandas在真实数据处理过程中把 Python 语法补起来。语法只有用到了才会真正记住。2. 搭建可复现的 Python 数据分析环境2.1 用 Miniconda 管理环境和依赖数据分析项目最怕依赖冲突。今天给 A 项目装 pandas 2.0明天给 B 项目装 pandas 1.5如果都装在系统 Python 里早晚会把环境弄坏。推荐使用 Miniconda 创建独立环境不同项目使用不同环境。安装完成后打开命令行工具执行conda create -n data_analysis python3.11 -y conda activate data_analysis这里以 Python 3.11 为例实际安装时选择当前稳定的 3.11 或 3.12 版本即可。环境创建成功后命令行前面会出现(data_analysis)前缀说明已经进入独立环境。每次打开新的终端窗口都要先执行conda activate data_analysis否则后面安装的库会装到错误环境里。这一点是新手最容易犯的错误之一。2.2 安装核心库并确认版本数据分析路线最常用的库有这些库主要用途建议安装方式pandas数据处理DataFrame 结构pip install pandasnumpy数值计算数组运算安装 pandas 时通常自动带matplotlib基础绘图pip install matplotlibseaborn统计图表基于 matplotlibpip install seabornscikit-learn数据挖掘入门简单模型pip install scikit-learnopenpyxl读写 Excel 文件pip install openpyxljupyter交互式笔记本pip install jupyter执行安装pip install pandas numpy matplotlib seaborn scikit-learn openpyxl jupyter安装完成后用一个简短脚本确认环境可用import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns print(pandas, pd.__version__) print(numpy, np.__version__) print(seaborn, sns.__version__)能正常打印版本号说明环境已经可用。注意不同时期安装的版本号可能不同只要导入不报错即可不需要追求最新。如果安装速度慢可以使用国内镜像源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pandas numpy matplotlib seaborn scikit-learn openpyxl jupyter2.3 练习数据集和项目目录规划没有数据就无法练习。初学者可以按优先级选这几种数据来源自己造的模拟数据用np.random生成订单、用户、销售数据适合练习清洗流程。开源数据集平台包含电商、金融、天气、交通等多类数据集适合练习业务分析。公司或竞赛脱敏数据集如果已经在相关行业工作用脱敏后的真实数据最有助于理解业务。无论数据来自哪里项目目录都要固定结构。推荐按下面的方式组织data_analysis_project/ ├── data/ │ ├── raw/ # 原始数据不修改 │ └── clean/ # 清洗后的数据 ├── notebooks/ # 探索性分析 notebook ├── scripts/ # 可执行的 Python 脚本 └── output/ # 图表和报告原始数据放在 raw 目录后不再改动清洗结果统一写入 clean 目录图表和报告放入 output 目录。这样的结构在找工作写项目时非常有用面试官一眼就能看出你的工程素养。注意原始数据不要直接覆盖。清洗前保留一份备份所有修改都在副本或清洗结果上完成否则一旦处理逻辑写错原始数据无法恢复。3. 数据清洗pandas 操作中的核心套路3.1 读取数据后的第一件事结构体检读取数据的代码很简单难的是读完之后知道自己该干什么。下面以一份电商订单表为例假设文件是data/raw/orders.csvimport pandas as pd df pd.read_csv(data/raw/orders.csv, encodingutf-8-sig) print(行数、列数:, df.shape) df.info() df.head()df.info()会输出每一列的名称、非空数量和数据类型。这一步能发现三个最基础的问题哪些列有缺失值缺失了多少。哪些列的类型不对比如金额被读成了字符串。数据规模有多大决定后续处理方式。df.describe(includeall)可以看数值列的统计量print(df.describe(includeall))如果某一列明明是订单金额但max或者mean看起来不合理说明原始数据里大概率混入了异常值、文本或单位不统一的数据需要进入下一步清洗。结构体检虽然简单但必须养成习惯。不做体检直接开始画图很可能画出一张充满错误数据的图后续所有结论都会被质疑。3.2 缺失值处理删除、填充还是标记处理缺失值没有万能方法核心原则是先看缺失比例再决定策略。# 查看每列缺失数量 print(df.isnull().sum()) # 查看缺失比例 print(df.isnull().mean().round(4))常见的处理方式有三种适用场景完全不同策略适用场景示例删除行缺失比例小且该记录不影响整体订单金额缺失记录不足总数据 1%填充缺失比例适中且字段有合理填充值用户年龄用中位数填充时间序列用前向填充标记缺失本身可能代表业务含义退款时间为空表示未退款单独建列标记示例代码# 删除关键字段为空的行 df df.dropna(subset[order_id, amount]) # 用中位数填充金额缺失 df[amount] df[amount].fillna(df[amount].median()) # 标记退款时间为空的状态 df[is_refunded] df[refund_date].notna().astype(int)这里要特别提醒用fillna(df[amount].median())填充必须先确认该列已经是数值类型否则填进去会报错或产生错误结果。另外不要无脑把整列缺失值填成 0因为 0 是真实数值会影响后续统计结论。3.3 重复值、异常值和类型转换重复值往往比缺失值更容易被忽略。检查重复行和指定列重复# 整行完全重复 print(完全重复行数:, df.duplicated().sum()) # 按订单号检查重复 print(订单号重复数量:, df.duplicated(subset[order_id]).sum()) # 删除重复订单保留第一个 df df.drop_duplicates(subset[order_id], keepfirst)类型转换是清洗另一个重点。最常见的问题是金额、数量被读成字符串# 将金额转成数值类型无法转换的变成 NaN df[amount] pd.to_numeric(df[amount], errorscoerce) # 将日期转成 datetime 类型 df[order_date] pd.to_datetime(df[order_date], errorscoerce)errorscoerce的作用是遇到无法转换的值时不是直接报错终止而是填成 NaN。这样既能保留其他正常数据又能通过后续缺失值处理发现脏数据。转换完成后要再次用df.info()确认类型变化。异常值处理常用 IQR 四分位距法Q1 df[amount].quantile(0.25) Q3 df[amount].quantile(0.75) IQR Q3 - Q1 lower Q1 - 1.5 * IQR upper Q3 1.5 * IQR outliers df[(df[amount] lower) | (df[amount] upper)] print(IQR 判断的异常订单数:, outliers.shape[0])异常值不一定要删除可以先单独分析。比如订单金额特别大的订单可能是大客户采购也可能是录入错误需要结合业务判断。直接删除异常值属于危险操作除非你能明确说明为什么这些记录不该参与分析。3.4 字段标准化日期、文本和类别处理字段标准化解决的是“同一个意思多种写法”的问题。比如城市列里既有“北京市”又有“北京”分类列里“男装”和“男士服装”其实是一回事。日期标准化# 统一为年月日格式 df[order_date] pd.to_datetime(df[order_date]).dt.strftime(%Y-%m-%d) # 提取年月方便做月度分析 df[order_month] pd.to_datetime(df[order_date]).dt.to_period(M)城市和分类文本标准化def normalize_city(value): if not isinstance(value, str): return value value value.strip().replace(市, ) return value df[city] df[city].apply(normalize_city)类别列可以用pd.Categorical转成分类类型能减少内存占用df[category] df[category].astype(category) print(df[category].cat.categories)清洗完成后把结果保存到 clean 目录df.to_csv(data/clean/orders_clean.csv, indexFalse, encodingutf-8-sig)保存时加indexFalse避免把 pandas 的行号写进文件使用utf-8-sig编码方便 Excel 打开时中文不乱码。这两个参数很小但实际工作中经常遇到值得养成习惯。4. 数据分析和挖掘从统计描述到业务洞察4.1 描述性统计和分组聚合清洗完成后第一轮分析从描述性统计开始print(df[amount].describe())输出结果会包括 count、mean、std、min、25%、50%、75%、max。通过这些指标可以判断数据的集中趋势和离散程度。比如中位数明显小于平均值说明数据右偏少数高金额订单拉高了均值。分组聚合是数据分析最核心的操作。用groupby按维度拆分再按指标聚合# 按城市汇总销售额 city_stats df.groupby(city)[amount].agg([sum, mean, count]) city_stats city_stats.sort_values(sum, ascendingFalse) print(city_stats.head(10))agg可以一次传入多个聚合函数结果为每个城市输出总销售额、平均订单金额和订单数量。三个指标分别回答哪个城市贡献最大、哪个城市客单价高、哪个城市单量多。如果维度较多可以使用透视表pivot pd.pivot_table( df, valuesamount, indexcity, columnscategory, aggfuncsum, fill_value0 ) print(pivot.head())透视表适合观察两个维度交叉后的规律。比如某个城市在“数码”分类下销售额很高而另一个城市在“家居”分类下表现更好这些信息用分组聚合很难一眼看到。4.2 相关性分析找到关键影响因素当数据里有多个数值型字段时相关性分析可以快速判断字段之间是否存在线性关系。比如订单金额和购买数量、用户年龄、运费之间是否相关。numeric_cols df.select_dtypes(includenumber).columns corr_matrix df[numeric_cols].corr() print(corr_matrix[amount].sort_values(ascendingFalse))corr()默认计算皮尔逊相关系数取值范围是 -1 到 1。绝对值越接近 1线性关系越强接近 0 表示没有明显线性关系。要注意相关不等于因果两个字段同时上升可能是因为它们都受第三个字段影响。相关性结果适合用热力图可视化后面会给出代码。在探索阶段相关矩阵能帮你快速锁定值得深入研究的方向防止在没有关联的字段上浪费时间。4.3 从分析到挖掘RFM 用户分层数据挖掘并不等于复杂的机器学习模型。对入门者来说RFM 是理解“从数据到业务动作”的最佳案例。RFM 用三个指标描述用户价值Recency最近一次消费距今多少天越短越好。Frequency一段时间内消费次数越多越好。Monetary一段时间内消费总金额越高越好。先把订单数据按用户聚合import datetime as dt snapshot_date df[order_date].max() pd.Timedelta(days1) rfm df.groupby(user_id).agg( recency(order_date, lambda x: (snapshot_date - x.max()).days), frequency(order_id, count), monetary(amount, sum) ) print(rfm.head())再用分位数给每个用户打分rfm[R_score] pd.qcut(rfm[recency], 4, labels[4, 3, 2, 1]) rfm[F_score] pd.qcut(rfm[frequency].rank(methodfirst), 4, labels[1, 2, 3, 4]) rfm[M_score] pd.qcut(rfm[monetary].rank(methodfirst), 4, labels[1, 2, 3, 4]) rfm[rfm_score] ( rfm[R_score].astype(int) * 100 rfm[F_score].astype(int) * 10 rfm[M_score].astype(int) ) print(rfm[rfm_score].value_counts().sort_index())这里对 frequency 和 monetary 先做rank是为了避免相同数值太多导致qcut分位边界失败。RFM 最终得分可以进一步划分为高价值用户、潜力用户和流失风险用户这比单纯看订单总金额更能指导运营动作。注意RFM 的分位数切分依赖数据分布。如果数据量太小或者同一数值占比过高qcut会报错此时可以用cut手动指定阈值或者先对字段做 rank。5. 数据可视化让结论可以被看见5.1 matplotlib 的核心绘图逻辑matplotlib 的基本逻辑是先创建画布和坐标系再往坐标系里添加图形最后显示或保存。理解了这个流程就不会被各种绘图代码绕晕。import matplotlib.pyplot as plt # 解决中文显示问题 plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, Arial Unicode MS] plt.rcParams[axes.unicode_minus] False fig, ax plt.subplots(figsize(8, 5)) ax.bar([A, B, C], [120, 90, 150]) ax.set_title(分类销售额) ax.set_xlabel(分类) ax.set_ylabel(销售额) plt.tight_layout() plt.savefig(output/bar_example.png, dpi150) plt.show()这段代码演示了几个必须养成的习惯fig, ax plt.subplots()比plt.bar()更推荐因为你显式控制了坐标轴对象。plt.rcParams中的中文字体设置要放在绘图之前否则图例和标题会变成方块。plt.savefig保存图片dpi150保证清晰度。plt.tight_layout()避免标题和坐标轴标签被截断。在命令行脚本里使用 matplotlib图片不会自动弹出来。可以通过plt.savefig保存到磁盘再打开查看。5.2 seaborn 快速完成分析图表seaborn 在 matplotlib 之上封装了大量统计图表语法更接近数据分析场景。常见用法包括柱状图、箱线图、直方图、折线图和热力图。import seaborn as sns sns.set_style(whitegrid) # 城市销售额 Top 10 top_cities df.groupby(city)[amount].sum().sort_values(ascendingFalse).head(10) sns.barplot(xtop_cities.values, ytop_cities.index) plt.title(Top 10 城市销售额) plt.tight_layout() plt.show()seaborn 的 barplot 第一个参数是 x第二个是 y。如果不小心传反坐标系会旋转图像看起来容易混淆。建议绘制前先明确哪个字段放 x 轴、哪个字段放 y 轴。折线图适合看时间趋势daily_sales df.groupby(order_date)[amount].sum() sns.lineplot(datadaily_sales) plt.title(每日销售额趋势) plt.tight_layout() plt.show()直方图看分布sns.histplot(df[amount], bins50) plt.xlabel(订单金额) plt.ylabel(订单数) plt.title(订单金额分布) plt.tight_layout() plt.show()箱线图看分组差异sns.boxplot(datadf, xcategory, yamount) plt.xticks(rotation45) plt.title(各分类订单金额分布) plt.tight_layout() plt.show()箱线图能同时展示中位数、四分位范围、异常点非常适合比较多个组别之间的差异。如果某分类的箱子明显高于其他分类说明该分类客单价整体更高。相关性热力图可以用来配合 4.2 节的相关矩阵plt.figure(figsize(8, 6)) sns.heatmap(corr_matrix, annotTrue, cmapRdBu_r, fmt.2f) plt.title(数值字段相关性热力图) plt.tight_layout() plt.show()annotTrue会在格子里显示相关系数fmt.2f控制保留两位小数。需要先计算corr_matrix否则 heatmap 传入的数据不对图也会是空的。5.3 图表选型表业务问题对应什么图很多新手的问题是“会画图但不知道画什么”。下面这张表可以帮助判断业务问题推荐图表说明销售额随时间变化折线图横轴是时间纵轴是指标哪个城市销售额最高柱状图类别少用柱状图类别多用条形图订单金额如何分布直方图看集中趋势和偏态不同分类的金额差异箱线图看中位数、四分位和异常点两个数值字段的关系散点图看线性或非线性趋势多个字段的相关性热力图快速发现强相关字段占比结构饼图或堆积柱状图类别少时可用类别多建议用柱状图饼图在入门项目里很常见但实际企业汇报中不建议过多使用。因为人眼对角度和面积的判断不如对长度准确类别超过 5 个时饼图几乎无法阅读。能用柱状图说明的问题优先用柱状图。6. 一个完整小项目从订单数据清洗到可视化报告6.1 项目场景和模拟数据说明为了让整个学习过程有一个完整的输出这里设计一个最小但完整的电商销售分析项目。场景是某电商平台有一张订单表orders.csv包含订单号、用户编号、下单日期、城市、商品分类、订单金额和订单状态。目标是回答四个问题每天销售额的总体趋势是怎样的。哪些城市贡献了主要销售额。订单金额的分布是否合理。各商品分类的表现如何。项目中我没有使用真实文件而是用代码生成一份带脏数据的模拟订单表。这样任何人都能复现。生成数据属于练习用途实际项目中同样建议先用小规模数据验证脚本逻辑再运行到全量数据上。生成模拟数据的脚本如下import pandas as pd import numpy as np np.random.seed(42) n 2000 order_ids [O str(i).zfill(6) for i in range(n)] cities [北京, 上海, 广州, 深圳, 杭州, 成都, 武汉, 西安] categories [数码, 家居, 服饰, 食品, 美妆] df pd.DataFrame({ order_id: order_ids, user_id: np.random.randint(1001, 1100, n), order_date: pd.date_range(2025-01-01, periodsn, freq4h).strftime(%Y-%m-%d), city: np.random.choice(cities, n), category: np.random.choice(categories, n), amount: np.round(np.random.lognormal(mean4.2, sigma0.6, sizen), 2), status: np.random.choice([已完成, 已取消, 退款中], n, p[0.8, 0.15, 0.05]) }) # 故意制造脏数据缺失、重复、文本混入 df.loc[50, amount] np.nan df.loc[120, amount] 未知 df.loc[200, city] 北京 df.loc[210, city] 北京市 df.loc[300, status] 已完成 df.loc[400, order_date] 2025/02/30 # 非法日期 # 增加一个完全重复的订单 df pd.concat([df, df.iloc[[0]]], ignore_indexTrue) df.to_csv(data/raw/orders.csv, indexFalse, encodingutf-8-sig) print(模拟数据已生成:, df.shape)这段代码故意制造了缺失值、文本混入、城市名称不统一、非法日期和重复记录。后面的清洗流程会针对这些问题逐一处理。模拟数据只用于演示思路实际项目中要使用真实业务数据字段名和脏数据形式会有差异但处理逻辑是相通的。6.2 清洗模块把脏数据变成可分析的数据在scripts/clean_orders.py中写入清洗逻辑import pandas as pd df pd.read_csv(data/raw/orders.csv, encodingutf-8-sig, dtype{order_id: str}) # 1. 删除完全重复行 before df.shape[0] df df.drop_duplicates() print(f去重: {before} - {df.shape[0]}) # 2. 关键字段缺失删除 df df.dropna(subset[order_id, amount]) # 3. 金额转数值 df[amount] pd.to_numeric(df[amount], errorscoerce) df df.dropna(subset[amount]) # 4. 日期解析非法日期变 NaN再删除 df[order_date] pd.to_datetime(df[order_date], errorscoerce) df df.dropna(subset[order_date]) # 5. 城市标准化 def normalize_city(value): if not isinstance(value, str): return value return value.strip().replace(市, ) df[city] df[city].apply(normalize_city) # 6. 只保留已完成订单 df df[df[status] 已完成].copy() # 7. 保存清洗结果 df.to_csv(data/clean/orders_clean.csv, indexFalse, encodingutf-8-sig) print(清洗后数据:, df.shape) print(df.info())关键点在于每一步之后都会打印或观察结果。清洗脚本每次运行后都应输出从多少行变成多少行方便追踪数据丢失是否合理。如果清洗后数据量骤减要回头检查是不是某一步过滤条件写错了而不是直接认为脚本执行成功。这里使用.copy()避免后续操作触发SettingWithCopyWarning。这个警告本身不一定是错误但它提示你可能在修改一个视图而不是原始数据实际项目里建议一律避免。6.3 分析模块算指标、找规律在scripts/analyze_orders.py中写入分析逻辑import pandas as pd df pd.read_csv(data/clean/orders_clean.csv, encodingutf-8-sig) df[order_date] pd.to_datetime(df[order_date]) # 总体指标 total_amount df[amount].sum() avg_amount df[amount].mean() order_count df.shape[0] print(f总销售额: {total_amount:,.2f}) print(f订单数量: {order_count}) print(f平均订单金额: {avg_amount:.2f}) # 每日销售额 daily df.groupby(order_date)[amount].sum().reset_index() print(\n销售额最高的 5 天:) print(daily.sort_values(amount, ascendingFalse).head(5)) # 城市排名 city_stats df.groupby(city)[amount].agg([sum, mean, count]).sort_values(sum, ascendingFalse) print(\n城市销售额排名:) print(city_stats.head(5)) # 分类统计 category_stats df.groupby(category)[amount].agg([sum, count]).sort_values(sum, ascendingFalse) print(\n分类排名:) print(category_stats)这些代码回答的都是业务问题。输出结果在命令行中可以直接看到但更直观的表达还是依赖可视化模块。6.4 可视化模块输出图表和结论在scripts/visualize_orders.py中写入绘图逻辑import pandas as pd import matplotlib.pyplot as plt import seaborn as sns plt.rcParams[font.sans-serif] [SimHei, Microsoft YaHei, Arial Unicode MS] plt.rcParams[axes.unicode_minus] False sns.set_style(whitegrid) df pd.read_csv(data/clean/orders_clean.csv, encodingutf-8-sig) df[order_date] pd.to_datetime(df[order_date]) fig, axes plt.subplots(2, 2, figsize(14, 10)) # 图 1每日销售额趋势 daily df.groupby(order_date)[amount].sum() sns.lineplot(datadaily, axaxes[0, 0]) axes[0, 0].set_title(每日销售额趋势) axes[0, 0].tick_params(axisx, rotation45) # 图 2Top 10 城市销售额 top_cities df.groupby(city)[amount].sum().sort_values(ascendingFalse).head(10) sns.barplot(xtop_cities.values, ytop_cities.index, axaxes[0, 1]) axes[0, 1].set_title(Top 10 城市销售额) axes[0, 1].set_xlabel(销售额) # 图 3订单金额分布 sns.histplot(df[amount], bins50, axaxes[1, 0]) axes[1, 0].set_title(订单金额分布) axes[1, 0].set_xlabel(订单金额) axes[1, 0].set_ylabel(订单数) # 图 4各分类销售额箱线图 sns.boxplot(datadf, xcategory, yamount, axaxes[1, 1]) axes[1, 1].set_title(各分类订单金额分布) axes[1, 1].set_xlabel(商品分类) axes[1, 1].set_ylabel(订单金额) axes[1, 1].tick_params(axisx, rotation45) plt.tight_layout() plt.savefig(output/sales_analysis.png, dpi150) plt.show()运行验证cd data_analysis_project python scripts/clean_orders.py python scripts/analyze_orders.py python scripts/visualize_orders.py正常结果应该是在命令行看到清洗前后的行数变化、总销售额和排名信息同时在output目录下生成sales_analysis.png。如果脚本在第三步报错通常要回到清洗脚本检查是否有列类型不对或字段名不一致。注意不要只验证程序能启动还要逐项核对输出文件的行数、图表中的数值和清洗日志是否一致。一个常见问题是清洗脚本本身语法没问题但统计结果明显偏低或偏高这种情况往往是某一步过滤条件写错了。7. pandas 常见报错与排查路径7.1 排错顺序从输入到输出的五层检查数据分析和清洗脚本报错最忌讳的是直接去搜索引擎复制别人代码然后盲目试。按照固定的排查顺序大部分问题几分钟内就能定位。推荐顺序输入是否正确文件路径、文件名、编码、分隔符是否正确。字段是否存在列名是否有空格、大小写、不可见字符。数据类型是否正确字符串和数值混在一起是高频问题。环境和依赖版本是否装错环境版本之间是否有 API 变更。业务逻辑是否正确脚本能跑不代表结果正确需要人工核对。前四层解决“程序不报错”最后一层解决“结果对不对”。实际工作中花在第 5 层的时间往往比前四层更多。7.2 高频报错对照表报错现象常见原因排查方式处理建议UnicodeDecodeError: utf-8 codec cant decodeCSV 文件是其他编码用记事本打开文件看编码改用encodinggbk或encodingutf-8-sigKeyError: order_date列名不存在或大小写不一致打印df.columns对比确认列名后修改代码列名最好先去空格SettingWithCopyWarning在切片视图上赋值看提示指向的行号使用.copy()或改用.loc[]TypeError: unsupported operand type(s) for : int and str数值列被读成字符串df.dtypes检查类型使用pd.to_numeric转换图表中文显示为方块字体未设置或系统无中文字体打印可用字体列表设置plt.rcParams[font.sans-serif]conda: command not foundconda 未加入 PATH检查安装目录使用完整路径启动或重新配置环境变量ValueError: Bin edges must be uniqueqcut分位边界重复检查字段分布先rank或改用cut指定边界读取 CSV 后所有数据都是 NaN分隔符不是逗号查看文件原始内容指定sep或检查表头是否包含干扰字符以上每一条都在实际项目中出现过不是理论问题。尤其是编码和列名问题几乎每个初学者都会遇到两次以上。7.3 一个完整排查实例订单表读进来全是空值现象执行pd.read_csv(orders.csv)后df.head()显示所有列都是 NaN但文件里明明有数据。排查过程第一步检查文件原始内容head -n 5 orders.csv如果发现列之间是用分号分隔的就定位了根因。CSV 的全称是 Comma-Separated Values默认分隔符是逗号但很多财务或业务系统导出的文件实际用的是分号或制表符。第二步确认分隔符后调整读取参数df pd.read_csv(orders.csv, sep;, encodingutf-8-sig)第三步检查表头是否错位。如果原始文件第一行是中文说明文字而不是列名需要用headerNone然后手动指定列名df pd.read_csv(orders.csv, headerNone, names[order_id, user_id, order_date, city, category, amount, status])这个实例的启示是读取阶段的问题必须回到文件本身找答案而不是改代码参数盲猜。先看文件前几行再看分隔符和编码最后调整 read_csv 参数。8. 一个月之后如何真正具备就业竞争力8.1 学习环境与工作环境的差异一个月学完可以做项目但这和实际岗位要求之间还有距离。下面这些差异要提前知道维度学习环境工作环境数据质量练习题相对干净数据来自多个系统字段含义靠对口径数据规模几千行千万行甚至上亿行指标口径自己定义需要和业务方对齐口径不同结论完全不同代码要求能跑出结果可维护、可回归异常处理完善交付物图表和 notebook分析报告、数据产品、监控看板如果你打算用一个月后的项目去求职至少要做到代码能从 raw 数据一键跑到输出图表不能只给别人看 notebook 里的散落代码。能重复执行、结果稳定的脚本才是项目级的交付物。8.2 一个月后必须完成的作品集清单一个月结束前建议对照以下清单检查自己的准备情况至少 2 个完整项目每个项目都有原始数据、清洗脚本、分析脚本、可视化图表和结论文档。所有脚本可以一键运行不依赖手动点击 notebook 单元。能用一张图加 3 句话解释一个业务问题。能回答下面这些高频面试题你清洗数据时遇到的最大问题是什么为什么选择用中位数而不是平均值填充如何判断一个字段是异常值还是真实业务数据项目中至少包含一种数据挖掘方法RFM 用户分层是最低要求。除 pandas 外能完成简单 SQL 查询比如GROUP BY、JOIN、WHERE。可以在一个月结束时把自己的项目代码放到代码托管平台并在简历中写清楚项目目标、数据规模、处理流程和最终结论。简历上的项目经验不需要多但每个项目都要经得起追问。8.3 后续三个月的进阶路线一个月能完成从零到一的跨越但“精通”还需要更长时间的业务沉淀和技术积累。后续三个月建议按这个路线推进第 2 个月补 SQL 和统计学基础重点学习假设检验、分布、抽样把“能算指标”升级为“能判断指标差异是否显著”。第 3 个月深入学习 pandas 性能优化、大数据量处理思路学习用 PySpark 或 DuckDB 处理更大规模数据。第 4 个月进入业务分析方向学习指标体系设计、A/B 测试、漏斗分析把数据挖掘方法应用到真实业务问题。一个月学习计划本质上是建立一条主线会读数据、会清洗、会分析、会展示、会写项目。后续所有进阶内容都是在这些基础能力之上叠加业务理解、更大数据规模和更复杂的模型。面试时面试官真正想看到的不是你背了多少 API而是你能否拿到一堆脏数据后一步步把它变成可解释的结论并能说明白每一步为什么这么做。
返回列表