很多想进入数据分析方向的学习者,最初的困境往往不是找不到资料,而是资料太多、路线太散。今天收藏一个“Python 基础速成”,明天看一段“Excel 数据透视表”,后天又去翻“SQL 面试题”,一个月下来只积累了碎片,没有形成能独立处理数据的能力。更有效的方法是先确定一条技术主线:从数据清洗、数据分析、数据挖掘到数据可视化,围绕 Python 生态的 pandas、Matplotlib、Seaborn 和 scikit-learn 按项目推进。这套 30 天学习方案的目标不是把教材看完,而是用四周时间完成几个可运行、可解释、可写进简历的数据项目。只要进入学习状态后能坚持每天动手 2 到 3 小时,按照文章里的清单逐步执行,数据分析和数据挖掘的入门链路是可以走通的。
1. 学习前先判断:你目标岗位要的技能树是什么
1.1 数据分析、挖掘、清洗和可视化到底在解决什么问题
数据清洗解决的是数据质量,数据分析解决的是“发生了什么、为什么会发生”,数据可视化解决的是“怎样把结论表达清楚”,数据挖掘解决的是“能不能根据历史数据预测趋势或发现隐藏结构”。这四者不是并列关系,而是一条流水线:拿到原始数据之后,先清洗,再分析,再用图表辅助判断,最后进入挖掘和建模。
实际项目中的典型顺序是:读取原始表 -> 检查字段类型、缺失值、重复值 -> 清洗和特征加工 -> 分组统计、相关性分析、可视化 -> 划分训练集和测试集 -> 建立分类或回归模型 -> 用评价指标判断模型是否可用。大多数面试问“数据分析流程”,想听的正是这条链路,而不是某一门工具的孤立技巧。
一个容易混淆的地方是数据分析的数据挖掘的区别。数据分析更多依赖统计汇总、业务对比、分组透视,能用 SQL、Excel 或 pandas 完成;数据挖掘则通常要借助机器学习算法,比如决策树、随机森林、聚类算法,目标是从数据中学习规律。数据可视化横跨两者,既能用来做探索性分析,也用来展示模型效果和分析结论。
1.2 这套 30 天路线适合谁
最适合的是三类人:完全没有编程基础、想转行数据分析的应届生;已经在用 Excel 做报表、想提升自动化能力的运营或业务人员;以及刚学过 Python 基础但不知道下一步做什么的开发者。
不同起点的调整策略差别很大。零基础的人不要在第 1 天就去啃 numpy 矩阵运算,先用 pandas 的数据结构建立“表格操作”的手感,遇到统计概念再回头补公式。有 Excel 经验的人可以把熟悉的“排序、筛选、去重、透视表”与 pandas 语法做对照,上手速度会明显更快。已经会 Python 基础的人可以直接跳到 pandas 和数据清洗部分,同时把 SQL 和项目报告作为重点练习。
1.3 学习关键词和能力要求速查表
下面这些术语在学习过程中会反复出现,先建立一个对照关系,后续遇到不理解的代码时能更快定位问题。
| 关键词 | 一句话说明 | 在项目中的位置 |
|---|---|---|
| 数据分析 | 用统计和查询方法描述数据规律 | 分组统计、对比分析、漏斗分析 |
| 数据清洗 | 处理缺失、重复、异常、格式不一致 | 建模之前的必要步骤 |
| 数据预处理 | 编码转换、归一化、类型转换 | 特征工程中的基础工作 |
| 数据挖掘 | 从数据中训练模型、发现规律 | 分类、回归、聚类、关联规则 |
| 数据可视化 | 用图表表达分析结论 | 探索分析、报告输出、结果展示 |
| 特征工程 | 把原始字段加工为更有解释力的输入 | 建模前的字段筛选和生成 |
2. 环境准备:用一套稳定配置跑完 30 天
2.1 Python 版本与包管理方式
学习数据分析并不需要追求最新版本的 Python。常见主流数据科学库通常优先支持较稳定的 Python 版本,建议使用 Python 3.10 或 3.11。如果你本机已经安装了 Python 3.9 或 3.12,代码一般也能运行,但在安装某些依赖前要先确认其支持情况。
不要直接往系统 Python 里堆安装包。每个学习项目最好都有独立虚拟环境,这样不会因为某个库升级影响另一个项目。这一习惯越早养成越好,它会直接影响你后续处理真实项目时的隔离能力。
2.2 创建虚拟环境并安装依赖
打开终端后,先在一个干净目录里建立项目文件夹。
mkdir 30days_data_analysis cd 30days_data_analysis python -m venv venvWindows 环境下激活虚拟环境:
venv\Scripts\activatemacOS 和 Linux 环境下激活虚拟环境:
source venv/bin/activate激活成功后,终端提示符会出现(venv)。然后用 pip 安装依赖。
pip install numpy pandas matplotlib seaborn scikit-learn openpyxl jupyterlab为了后续能重复安装,把依赖导出到 requirements 文件更规范。
pip freeze > requirements.txt如果学习过程中下载速度较慢,可以临时切换镜像源,但这只影响安装渠道,不影响后续代码写法。安装完成后,启动 JupyterLab。
jupyter lab2.3 建议的数据目录结构
完整的数据项目通常不是把一个脚本写完就结束,而需要区分原始数据、处理脚本和输出文件。
30days_data_analysis/ ├── data/ │ ├── raw/ # 存放原始数据,尽量不手动改动 │ └── processed/ # 保存清洗后的数据 ├── notebooks/ # 存放探索阶段的 Notebook ├── scripts/ # 存放入口脚本和函数模块 ├── output/ # 图表和最终结果 ├── requirements.txt └── README.md学习环境可以只建data和notebooks两个目录,但加上processed和output后,你会更早适应“数据不能原地覆盖”的工作习惯。原始数据是资产,清洗代码也是资产,总想着把原始表改来改去,最终很容易出现结果不可复现的问题。
3. 第一阶段(第 1 到 7 天):用 Pandas 建立数据操作手感
3.1 Python 基础不需要学完再动手
很多新手卡在第 1 天,是因为想先掌握 Python 全部语法再开始数据分析。实际上,入门阶段只需要掌握变量、列表、字典、for 循环、if 判断、函数定义和列表推导式,就可以开始 pandas 操作。遇到集合、异常等更多语法时,再通过报错和搜索逐步补上。
推荐学习项目是:用 Python 读取一个 CSV 文件,统计文件的行列数、字段名称和缺失情况。这个任务会自然用到文件路径、类型、函数和条件判断,比单独背语法更容易坚持。
3.2 从零创建一份订单样例数据
为了不在第 1 周就被下载数据的各种问题打断,可以先直接构造一份小型订单数据。下面代码演示 pandas 的核心入门操作。
import pandas as pd data = { "订单ID": ["A001", "A002", "A003", "A004", "A005"], "城市": ["北京", "上海", "广州", "北京", "上海"], "商品分类": ["数码", "服装", "数码", "食品", "服装"], "销售额": [1200, 300, 2400, 80, 500], "成本": [800, 150, 1800, 50, 300], "日期": ["2024-01-01", "2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05"], } df = pd.DataFrame(data) print(df) print(df.info()) print(df.describe())输出会先显示完整的 DataFrame,然后显示每列的非空数量和数据类型,最后显示销售额、成本等数值列的五数概括。这组输出已经能回答最基本的数据问题:表有多大、每个字段有没有空值、字段类型是否合理。
日常学习中,可以用df.head()查看前几行,用df.shape看行列数,用df.columns看列名,用df["城市"].value_counts()做分组计数。掌握这些方法后,面对任何表格数据都不会不知道从哪里开始。
3.3 用 pandas 复制 Excel 核心操作
做过 Excel 的人可以把 pandas 语法与 Excel 功能对照起来记忆。
| Excel 操作 | pandas 写法 | 说明 |
|---|---|---|
| 筛选某城市 | df[df["城市"] == "北京"] | 返回布尔索引对应的行 |
| 排序 | df.sort_values("销售额", ascending=False) | 按销售额降序排序 |
| 透视表 | df.pivot_table(index="城市", values="销售额", aggfunc="sum") | 统计各城市销售额合计 |
| 去重 | df.drop_duplicates(subset=["订单ID"]) | 按指定列去重 |
| 新增列 | df["毛利"] = df["销售额"] - df["成本"] | 对整列做减法运算 |
这一段阶段最容易犯的错误是过度依赖教程代码,不自己敲。pandas 的失败率很低,只要数据类型对、列名对,绝大多数代码都能运行。手动敲过一遍后,再回到代码中去理解“向量化运算”的概念,即 pandas 对一个 Series 整体做运算,不需要像普通循环那样逐行处理。
4. 第二阶段(第 8 到 14 天):数据清洗是决定项目质量的关键
4.1 数据清洗的核心任务分类
数据清洗不是一项单独的技术,而是一组围绕数据质量的动作。它至少包括几类:处理缺失值、处理重复值、处理异常值、统一字段格式、修正数据类型、处理文本中的空格和编码问题。真实数据里几乎不存在天然能直接使用的 CSV,清洗往往会占到整个项目 60% 以上时间。
清洗的目标是让数据达到“可分析、可建模”的状态。缺失值太多会导致统计结果偏差;重复记录会放大计数;日期列如果被读成字符串,则无法按时间排序和聚合;文本分类列如果带有不可见空格,value_counts()会把同一个城市拆成两个类别。
4.2 构造一份带脏数据的文件,完成第一次清洗
这里创建一个包含缺失、重复和类型问题的演示文件。先准备原始数据:
订单ID,城市,商品分类,销售额,日期 O001,北京,数码,200.00,2025/01/01 O002,,服装,,2025-01-02 O003,上海,数码,150.00,2025/01/03 O003,上海,数码,150.00,2025/01/03 O004,北京,食品,80.00,2025-01-03 O005, 广州,数码,,2025-01-05观察这份数据可以发现几个典型问题:第二条城市和销售额缺失;第三和第四条是重复记录;部分城市名称有前导空格;日期列同时存在斜杠和横线两种分隔形式;销售额列带小数点和空值。先用 pandas 读取并检查。
import pandas as pd df = pd.read_csv("data/raw/sales_dirty.csv", encoding="utf-8") print(df.info()) print(df.head(10))read_csv()默认把销售日期读成字符串,因为两种日期格式混用。日期处理的推荐做法是先统一格式,再转为 datetime 类型。
4.3 清洗代码示例与每一步的原因
下面代码覆盖了常见的清洗动作:
# 1. 去空格和统一文本格式 df["城市"] = df["城市"].str.strip() # 2. 删除完全重复的行 df = df.drop_duplicates().copy() # 3. 丢弃订单ID为空的行,因为无法定位业务对象 df = df.dropna(subset=["订单ID"]).copy() # 4. 统一日期格式并转为 datetime df["日期"] = pd.to_datetime(df["日期"], format="mixed", dayfirst=False) # 5. 将销售额转为数值,无法转换的部分记为 NaN df["销售额"] = pd.to_numeric(df["销售额"], errors="coerce") # 6. 对缺失销售额做按城市均值填充 avg_by_city = df.groupby("城市")["销售额"].transform("mean") df["销售额"] = df["销售额"].fillna(avg_by_city) # 7. 重置索引 df = df.reset_index(drop=True) print(df.info()) print(df)代码中的重点是drop_duplicates()用来删除完全相同的行,subset参数可以指定只根据某几列去重,更符合“业务上重复”的定义。errors="coerce"的作用是把无法转换的值变成缺失值,而不是让程序报错,这样后续可以用填充策略统一处理。用分组均值而不是全局均值填充,能减少地域差异对销售额估计的干扰。
清洗完成后不要直接覆盖原始文件。将结果写入processed目录,并使用新文件名。
df.to_csv("data/processed/sales_clean.csv", index=False, encoding="utf-8-sig")注意这里使用了utf-8-sig,为什么?因为清洗后的文件通常要用 Excel 打开,不带 BOM 的 UTF-8 文件在 Excel 中可能出现中文乱码。这个细节很常见,却经常导致项目汇报时前功尽弃。
4.4 清洗阶段最容易踩的三个坑
第一个坑是直接修改原始文件。如果清洗逻辑写错了,原始数据又已经被覆盖,整个项目就没有恢复依据。一定要保存一份 raw 数据,并把清洗脚本保存下来。
第二个坑是没有在去重前检查去重依据。同一个订单确实可能因为系统问题生成两次,但也可能两个不同订单在城市、金额和日期上完全相同。单纯把所有行都去重,会误删有意义的数据。正确方式是先按业务主键判断,比如订单ID。
第三个坑是看到缺失值就想到删除。不同特征的缺失率、缺失原因和业务含义不同。如果一个字段缺失 80%,删除整列更合理;如果只是个别行缺失,可以考虑删除行、填充均值、填充中位数或使用前向填充。没有固定规则,规则要根据分析场景和数据分布确定。
5. 可视化模块:把分析结论变成可信的图表
5.1 先从 Matplotlib 入手,再用 Seaborn 加速
数据可视化需要同时掌握两个层面的技能:绘制图表的语法,以及判断某个图表是否适合当前数据。Python 生态中最常见的是 Matplotlib 和 Seaborn。Matplotlib 提供最底层的绘图控制,适合精确调整轴、标题、图例;Seaborn 构建在 Matplotlib 之上,用更短代码绘制出更美观的统计图表,尤其适合分布、热力图和分类散点图。
需要防止的误解是“图表越多越好”。可视化是用来辅助分析的,不是用来凑字数的。每画一张图之前,都应该问自己:这张图能验证什么假设,能回答什么问题?如果回答不出来,这张图就是噪音。
5.2 四类常见图表对应四类分析问题
| 分析问题 | 推荐图表 | 典型用途 |
|---|---|---|
| 某个数值变量分布 | 直方图、箱线图 | 看销售额是否偏态、是否有离群点 |
| 两个类别之间的比较 | 条形图、分组条形图 | 比较不同城市的平均销售额 |
| 两个数值变量的关系 | 散点图、回归图 | 看广告投入与销售额相关度 |
| 类别变量占比 | 饼图、水平条形图 | 查看商品分类占比,注意饼图不能分类太多 |
| 时间趋势 | 折线图 | 分析每天销售变化 |
5.3 用 seaborn 完成一组探索性图表
沿用前面清洗好的销售数据,加入城市和商品分类的统计信息。
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns df = pd.read_csv("data/processed/sales_clean.csv") plt.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "Arial Unicode MS"] plt.rcParams["axes.unicode_minus"] = False sns.set_theme(style="whitegrid") fig, axes = plt.subplots(1, 3, figsize=(14, 4)) # 第一个子图:销售额分布 sns.histplot(df["销售额"], bins=20, kde=True, ax=axes[0]) axes[0].set_title("销售额分布") # 第二个子图:各城市销售额合计 city_sales = df.groupby("城市", as_index=False)["销售额"].sum() sns.barplot(data=city_sales, x="城市", y="销售额", ax=axes[1]) axes[1].set_title("各城市销售额合计") # 第三个子图:商品分类金额箱线图 sns.boxplot(data=df, x="商品分类", y="销售额", ax=axes[2]) axes[2].set_title("不同商品分类销售额分布") axes[2].tick_params(axis="x", rotation=45) plt.tight_layout() plt.savefig("output/sales_analysis.png", dpi=150) plt.show()这段代码前两行的字体设置非常关键。Matplotlib 在默认设置下可能无法显示中文负号或中文标签,如果环境中的字体不是 SimHei,还需要安装或指定系统已有中文字体。最直接的验证方式是运行后观察坐标轴标签是否出现方框。
5.4 可视化时最容易犯的错误
新手最容易犯的错误是绘制出“无法比较”的图。比如想比较五个城市的销售额,却把城市放在连续 x 轴上,用折线图连接所有柱子,这种做法在语义上并不成立;或者饼图超过五个分类,让读者很难分辨面积。处理方法是优先使用水平条形图,并让数据按从大到小排序。另一个常见错误是所有图表都使用默认配色却不加注释,导致回看时忘了每张图当时验证了什么。建议每个图保存时都加上dpi=150,并在代码旁写上分析结论。
6. 数据挖掘入门:第 19 到 21 天用最小建模闭环跑通算法
6.1 从统计描述进入数据挖掘
完成清洗和可视化后,数据可以进入挖掘阶段。数据挖掘并不是一个黑盒,它解决的问题通常能被归纳为四类:分类问题,预测离散类别;回归问题,预测连续数值;聚类问题,把相似样本自动聚合到一起;关联规则问题,发现项目之间的共现关系。
初学阶段不建议一口气把所有算法都学完。推荐的学习顺序是:先学逻辑回归或决策树处理分类问题,再用一个简单回归问题加深对损失函数的理解,最后学 KMeans 聚类理解无监督学习。如果时间有限,至少要把“训练集和测试集划分、特征编码、模型训练、准确率评估”这四个环节亲手运行一遍。
6.2 分类模型的最小可运行代码
在真实项目中,需要先把类别型字段转换成模型能识别的数值型。下面使用城市、商品分类两个特征预测销售额是否大于平均值,这是一个二分类问题。
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score, classification_report df = pd.read_csv("data/processed/sales_clean.csv") # 构造二分类目标:销售额高于中位数记为1 target = (df["销售额"] > df["销售额"].median()).astype(int) df["是否高销"] = target # 选择特征并编码 df_model = df[["城市", "商品分类", "是否高销"]].copy() le_city = LabelEncoder() le_cat = LabelEncoder() df_model["城市编码"] = le_city.fit_transform(df_model["城市"]) df_model["分类编码"] = le_cat.fit_transform(df_model["商品分类"]) df_model["是否高销"] = df_model["是否高销"].astype(int) X = df_model[["城市编码", "分类编码"]] y = df_model["是否高销"] X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42 ) model = DecisionTreeClassifier(max_depth=3, random_state=42) model.fit(X_train, y_train) y_pred = model.predict(X_test) print("准确率:", accuracy_score(y_test, y_pred)) print(classification_report(y_test, y_pred))这里的LabelEncoder把城市名称变成 0、1、2 等数字,但要注意它只适合树模型。如果使用逻辑回归或线性模型,标签编码会被误认为有大小关系,比如“广州=1、北京=2”,这可能给模型带来错误的信息。在那些场景中通常要用独热编码pd.get_dummies()或OneHotEncoder。
随机森林、决策树这类模型对特征缩放不敏感,所以这里没有做归一化;但对逻辑回归和 KMeans 来说,特征缩放会影响结果,需要提前思考。
6.3 数据挖掘完成后别只报告准确率
准确率本身不足以说明模型是否可靠。如果数据中 90% 的标签是“不高销”,模型即使全部预测成“不高销”,准确率也能达到 90%,但它没有学习到任何有效规律。这就是为什么要看精确率、召回率和 F1 分数的原因。
| 指标 | 解决的问题 |
|---|---|
| 精确率 | 预测为正的样本中有多少是真的正 |
| 召回率 | 真正的正样本中模型找回了多少 |
| F1 | 精确率和召回率的综合平衡 |
| 混淆矩阵 | 查看模型在哪些样本上发生了错误 |
建议初学阶段把每个模型的输出都主动用classification_report打印一次,并写两三行注释解释结果。分析报告不能只贴一个数字,而要说清楚模型对哪类判断更好、误差集中在哪类样本上。
7. 第 22 到 28 天:用“招聘岗位分析”串起完整项目
7.1 项目背景和可以回答的问题
在这个阶段,可以用公开渠道采集的“数据分析岗位招聘数据集”作为训练材料。项目目标是分析市场需求、薪酬分布和技能要求。如果没有真实数据,也可以使用网上公开的课程练习数据集;这里重点不是数据的绝对真实程度,而是让你走完“读取、清洗、探索、可视化、建模、汇报”的完整流程。
围绕招聘数据,可以回答的问题包括:
- 数据分析岗位的薪资范围受城市、学历、经验年限的哪些因素影响?
- 不同城市对 Python、SQL、Excel 等技能的要求占比如何?
- 能否根据岗位描述中的关键词、城市和经验要求,预测岗位是否给出高于中位数的薪资?
- 业务型数据分析岗与技术型数据岗在岗位描述特征上有没有可量化的差异?
这些问题都不需要一开始就全部回答。选择一个更有业务价值的问题作为主线,其他问题作为扩展即可。
7.2 建议的项目结构
job_analysis/ ├── data/ │ └── job_posts.csv ├── notebooks/ │ ├── 01_explore.ipynb │ ├── 02_clean.ipynb │ └── 03_model.ipynb ├── scripts/ │ ├── data_clean.py │ └── feature_engineering.py ├── output/ │ ├── salary_by_city.png │ └── skill_require_top10.png └── README.md学习阶段不必管住所有工程细节,但坚持这个结构至少有几点好处:一是回滚方便,二是别人能看懂数据处理逻辑,三是自己的面试答辩能讲清楚。
7.3 招聘数据的清洗要点
招聘类数据常见问题非常多。薪资字段通常是字符串,例如“15K-25K·14薪”;经验字段可能出现“经验不限”“在校/应届/三年以上经验”等混合文本;技能要求分散在长文本描述中,难以直接变成特征。
薪资清洗可以先取区间上下限的平均值,把“15K-25K”转换为数字并计算均值为 20K;再看有没有“14薪”这样的打包描述,把它作为一年总收入的一部分。模型设计时,这个字段可能产生比较明显的区分信息,值得写成独立特征。注意:这样的处理会带来估算误差,写分析报告时一定要说明处理规则,不能把清洗后的估算值当成真实字段。
技能要求清洗常见的方式是做关键词匹配。如果岗位描述中出现了“Python”“python”“PYTHON”,就说明该岗位要求 Python 技能。在真实项目中,建议先把文本统一成小写,再使用正则表达式匹配,避免大小写导致漏判。
7.4 把结果写成可复现的分析报告
项目最后一天,要求自己输出一份报告,而不是只交代码。一份可复现的数据分析报告至少要包含六部分:
- 分析背景与问题定义。
- 数据来源、采集时间和处理规则。
- 清洗前后的数据规模变化。
- 图表展示和关键洞察。
- 建模方法、特征说明和评价指标。
- 结论、局限性以及后续可以扩展的方向。
建议使用 Jupyter Notebook 完整保留探索过程,再用 Markdown 写一份浓缩版结论。真正能证明能力的是,别人按你的数据路径和代码运行后能得到一致结果。
8. 第 29 到 30 天:用作品和面试题检验 30 天成果
8.1 适合扩展的两个练手项目方向
30 天结束后,可以把“招聘岗位数据分析”作为主项目继续打磨。如果还想增加新项目,有两个方向非常适合初学者:足球比赛数据分析,企业内部销售订单数据分析。
足球数据分析的原始数据通常是 CSV 或 JSON,包含球队、比赛时间、射门次数、控球率等字段。可以探索控球率与胜负的关系、主客场影响、比赛结果聚类等。这类项目的好处是数据天然结构化,领域问题也比较容易解释。相关热搜词中高频出现的“足球数据分析”正是这类方向。销售订单数据分析则更适合业务分析岗位面试,从订单、商品、门店、会员维度拆解 GMV 增长和滞后原因。
无论哪个方向,并不追求数据集越大越好。能证明清洗逻辑和处理思路合理,比用一个几十 GB 数据却只做 Excel 汇总更有说服力。
8.2 高频面试考点
数据分析面试通常考察三类能力:代码、业务和项目经验。
代码能力重点在 pandas 常见操作。面试里会给出一个 DataFrame,让候选人计算各城市的销售额排名、统计每月同比、找出重复订单、处理缺失值。回答这类题的思路仍然是一步一步来:先明确表结构,再明确输出格式,最后选择合适的聚合方法。
业务能力高频考点包括:指标下降后如何排查,如何做 AB 实验,如何评估某次活动效果。这类问题没有唯一答案,但回答时一定有结构化思维。可以按“指标拆解 -> 数据来源确认 -> 异动假设 -> 验证 -> 结论”的顺序作答。
项目经验一定会被问到:清洗过程中是否保留了原始数据,如何处理了异常值,特征工程中每一个特征是否具备业务解释。推荐准备一份 3 分钟项目答辩稿,用背景、方案、结果、复盘四个段落回答,不要只讲代码。
8.3 建议准备的技能权重参考
仅作为学习侧重点参考,实际岗位要求会随公司和行业变化。
| 技能 | 常见用途 | 建议能力 |
|---|---|---|
| Python / pandas | 清洗、处理、自动化 | 能独立完成完整清洗 |
| SQL | 取数、数据集验证 | 能写多表 join 和窗口函数 |
| 可视化 | 输出报告 | 能判断哪种图合适,并讲清楚结论 |
| 统计分析 | 验证业务结论 | 理解均值、中位数、分布、相关性 |
| 机器学习基础 | 预测和分类 | 能手写一个分类或回归流程 |
| 业务理解 | 项目定义和结论落地 | 能提出可执行建议 |
9. 从数据分析和挖掘延伸到数据工程时必须想清楚的事
9.1 数据分析师与数据工程师的边界
学习 30 天后,大概率会碰到“数据分析、数据工程、数据科学”这些职位名词。它们常常混在一起,但在实际团队中分工有较大区别。数据分析师更关注业务指标变化,需要能和运营、产品沟通,输出报告;数据工程师更关注数据链路能否稳定高效地流动,包括采集、同步、任务调度、数仓建模、监控告警;数据科学家通常介于研究和工程之间,更侧重建模和实验设计。
从求职角度看,当候选人投递数据分析岗位时,项目里要突出业务结论;投递数据工程相关岗位时,则需要补充调度、ETL、数仓层级和集群任务调度等实践。后面的“DE 和 DS”之争也多源于此,它们不是同一个岗位,学习路线不能互相套用。
9.2 Spark 和大数据为什么不是第一周的内容
30 天入门阶段不需要直接以 Spark 作为主线。单机 Python 和 pandas 能处理千万行以下数据,足够让初学者理解数据流程和方法论。Spark 解决的核心问题是分布式并行计算,它适合单表数据量超出单机内存、需要集群计算、或需要在统一计算框架里跑 SQL、批处理和流任务的场景。
如果已经完成本文的 30 天路线,而个人目标偏向“数据工程”,下一个学习阶段可以优先补齐:
- 用 SQL 在 Hive 或 ClickHouse 中做数据查询和清洗。
- 理解任务调度工具 Airflow、DolphinScheduler。
- 掌握 Spark DataFrame API 和常用算子,看两个 Spark 数据分析案例。
- 学习数据仓库建模,包括维度建模和事实表设计。
在学 Spark 之前,先考问一个问题:你在单机上是否已经能熟练完成数据清洗、代码模块拆分和结果验证?如果还没有,跳过基础去学分布式框架,只会让排查问题的工作量成倍增加。
9.3 生产环境与学习环境的差距
学习环境下,代码能跑通就视为成功;生产环境的标准要高得多。上线任何分析任务之前,要额外确认配置是否外置、日志是否完整、权限是否严格、任务是否支持断点恢复和数据回滚。
| 维度 | 学习环境 | 生产环境建议 |
|---|---|---|
| 数据获取 | 手工下载 CSV | 配置同步任务、版本管理、数据质量校验 |
| 代码运行 | Jupyter 手动运行 | 脚本化、参数化,支持任务调度 |
| 日志 | print 输出 | 记录日志,统一日志级别 |
| 敏感信息 | 无 | 脱敏处理,密钥走配置中心 |
| 失败恢复 | 重新运行 | 幂等设计,失败后能重跑 |
| 输出结果 | 本地图表 | 写入报表系统或数仓,并监控产出时间 |
这些内容不属于 30 天必须完成的范围,但越早意识到差异,越能避免把“能跑”误认为“上线可用”。
10. 30 天过程中最常见的报错与排查路径
10.1 pandas 读取文件后的常见问题排查
| 问题现象 | 可能原因 | 检查和解决路径 |
|---|---|---|
| 中文列名读出来是乱码或报错 | 文件编码不是 UTF-8 | 用df = pd.read_csv(path, encoding="gbk")或utf-8-sig逐个尝试 |
| 读取后列名带有空格 | 源文件字段中间有不可见字符 | 检查df.columns,用df.columns = df.columns.str.strip()清理 |
| 日期列是字符串无法排序 | 日期格式不统一 | 先统一为2025-01-01,再pd.to_datetime |
| 文件读取路径报 FileNotFoundError | 当前工作目录不对 | 用os.getcwd()查看目录,或改成绝对路径 |
| 统计结果偏大 | 没有处理重复值和缺失值 | 先drop_duplicates(),再按业务处理缺失 |
遇到问题时不要盯着报错信息最后一行死记。先看报错出现在哪一行,再判断是数据结构问题还是依赖版本问题。pandas 版本升级有时会改变一些默认参数,遇到不明报错时可以打印pd.__version__,再根据版本搜索。
10.2 可视化中文乱码的处理链路
如果图中中文都变成了方框,第一步不是换库,而是先确认环境中是否有可用中文字体。
import matplotlib.font_manager as fm fonts = [f.name for f in fm.fontManager.ttflist] print("SimHei" in fonts, "Microsoft YaHei" in fonts)如果列表中不存在中文字体,需要先安装系统字体,或者指定到已存在的字体文件路径。真实项目中不建议每次都写死本机字体,因为换一台机器就可能失效。更稳妥的方式是在项目 README 里说明字体依赖,或者在不要求中文标题时尽量用英文标签。
10.3 学习进度失控时的应对清单
30 天坚持下来的关键不是平均用力,而是给每个阶段设置“最小通过标准”。
| 时间 | 最小通过标准 |
|---|---|
| 第 7 天 | 能自己写代码读取 CSV 并按城市分组汇总 |
| 第 14 天 | 能独立完成一份含缺失、重复、格式问题的清洗 |
| 第 18 天 | 能画出一张走势图和一张对比条形图 |
| 第 21 天 | 能运行一次完整的分类建模并解释准确率 |
| 第 28 天 | 能写出一份带背景、代码、结论的 README 项目报告 |
如果某天没有完成任务,不建议熬夜补齐,而要在第二天把缺失队列排到最前。项目的连续性比某个知识点的完整性更重要,因为数据项目之间的关系是递进的,哪怕漏掉一个细节,后面的结果也可能出现偏差。
10.4 代码书写上的核心实践建议
不要在一个 Notebook 里堆砌所有步骤。推荐把公共清洗函数拆到scripts文件里,并在 Notebook 中通过import调用,这样能让探索过程和可复用代码分离。重要函数要有 docstring,说明输入是什么、输出是什么、做了哪些处理,方便自己回看也方便别人 review。
不要在代码中裸用print()作为唯一的验证方式。至少要在每个阶段用assert做一次简单检查,例如清洗完成后判断数据行数小于原始行数,或者日期列已经成功转为 datetime。
assert df["日期"].dtype == "datetime64[ns]" assert df.duplicated(subset=["订单ID"]).sum() == 0这种断言带来的价值是,后续修改清洗代码时能立即发现回归问题,而不是等到建模结果异常才回头找原因。
第 30 天结束时,真正应该收获的不是“学完了”的感觉,而是能围绕一份脏数据独立写出清洗代码、能用图表解释规律、能运行并评估一个简单分类模型,并把整个过程整理成别人能读懂的项目报告。只要完成这条链路,之后继续学习 SQL、Spark、数仓知识时,都能找到一个明确的问题定位:它们是为了让数据链路更可靠、让数据处理范围更大、让分析方法更高效,而不是替代你已经建立的数据处理思路。