数据分析是这几年被提到最多的技能之一,而 Python 几乎是它的代名词。2026 年 1 月 pandas 3.0 正式发布,加上 Polars、DuckDB 等新工具走向成熟,整个生态的玩法又悄悄变了一轮。这篇文章从零开始梳理一条完整的学习路线:先讲清楚数据分析到底在做什么,再讲工具怎么选、代码怎么写、弯路怎么避,适合作为从入门到精通的长期参考。
一、数据分析是什么,为什么非 Python 不可
数据分析的五步流程
无论分析的是销售报表还是比赛数据,基本流程都是五步:
- 获取:从 CSV、Excel、数据库、网页等渠道拿到原始数据
- 清洗:处理缺失值、重复行、格式错乱、异常值
- 探索:统计、分组、对比,找出数据的分布和规律
- 建模:用统计或机器学习方法做预测、分类(进阶可选)
- 呈现:用图表和报告把结论讲清楚
现实中,清洗和探索往往占去八成时间。带过新人的朋友大概都有体会:清洗没做完就急着建模,等于把一个垃圾算了一遍。
这里要早点想清楚一件事:数据分析不等于机器学习。工具是手段,把问题讲明白才是目的。
Python 胜出的原因
Python 不是最快的语言,却是数据分析领域事实上的标准,原因有三个:一是生态最全,从读取、计算到可视化、机器学习都有成熟库;二是语法简单,分析师可以把精力放在问题上而不是语言细节上;三是"胶水"能力强,慢的脏活累活可以交给底层 C、Rust 写的库去干,Python 只负责指挥。理解这一点,后面看到 Polars 用 Rust 重写底层却依然用 Python 写业务,就不会觉得奇怪了。
二、2026 年的工具版图:先认清四块基石
四块基石各管一件事
- NumPy:一切的地基,提供高效的多维数组和数学运算,pandas 底层就建立在它之上
- pandas:表格数据处理的主力,把数据当成类似 Excel 的二维表(DataFrame)来操作
- matplotlib / seaborn / plotly:可视化三剑客,分别对应底层绘图、统计图形、交互图表
- Jupyter / marimo:边写边看结果的工作环境。Jupyter 是老牌主流,marimo 是近两年走红的响应式新秀,单元格会自动联动重算、文件存成纯 .py 方便版本管理
大数据时代的新选择
当数据量上到百万行以上,老工具会吃力,新三样开始登场。先放一张对比表建立直觉:
| 工具 | 底层语言 | 执行方式 | 相对速度 | 内存占用 | 适合场景 |
|---|---|---|---|---|---|
| pandas | Python + C | 单线程、立即执行 | 基准 | 原始数据的 5 到 10 倍 | 中小数据、生态兼容 |
| Polars | Rust | 多线程、支持惰性求值 | 通常快 5 到 10 倍,部分场景 10 到 100 倍 | 原始数据的 2 到 4 倍 | 单机大数据、性能敏感 |
| DuckDB | C++ | 进程内 SQL 引擎 | 分析型查询极快 | 按需流式读取 | 直接用 SQL 查 CSV/Parquet |
三者不是替代关系,而是按需组合:pandas 负责灵活,Polars 负责快,DuckDB 负责用 SQL 思维处理大文件。后面第七节会展开讲。
三、入门第一步:环境搭建与第一行代码
装好环境只需要三条命令
2026 年学数据分析,建议直接装 Python 3.11 或更高版本(pandas 3.0 的最低要求),然后用 pip 安装核心库:
python --version
pip install pandas matplotlib jupyter如果你更习惯用 conda 管理环境,也可以这样:
conda create -n data python=3.12
conda activate data
pip install pandas numpy matplotlib jupyterlab版本上有个现实问题:Python 主版本更新很快,但 NumPy、pandas 这些库对新版本的适配总会有延迟。求稳的话,选 3.11 或者 3.12,别一上来就用刚发布的版本。
编辑器随喜好。想边写边看结果,JupyterLab 最合适;想写完整的脚本,VS Code 加一个 Python 插件就够。
第一个完整例子
新建一个 sales.csv,随便写几行销售记录(列:城市、金额),然后运行:
import pandas as pd
# 读取 CSV 文件
df = pd.read_csv("sales.csv")
# 看前 5 行长什么样
print(df.head())
# 数值列的统计概况:个数、均值、最值、分位数
print(df.describe())
# 行列数与每列的数据类型
print(df.shape)
print(df.dtypes)这五行代码已经走完了数据分析的第一步:把数据读进来并建立第一印象。后面的所有技巧,都是在这个基础上做更精细的筛选、计算和呈现。
四、核心武器 pandas:必须掌握的六件事
pandas 的功能很多,但日常八成的工作只用到六件事:选数据、过滤、算新列、分组聚合、处理缺失值、多表合并。下面一个例子把它们串起来:
import pandas as pd
df = pd.read_csv("orders.csv")
# 1. 选列与选行
df[["city", "amount"]] # 选两列
df.loc[0:4, ["city", "amount"]] # 按标签选前 5 行
df.iloc[0:5] # 按位置选前 5 行
# 2. 条件过滤:金额大于 100 的订单
big = df[df["amount"] > 100]
# 3. 新增计算列:含税金额
df["amount_with_tax"] = df["amount"] * 1.13
# 4. 分组聚合:每个城市的平均金额与订单数
summary = df.groupby("city").agg(
avg_amount=("amount", "mean"),
order_count=("amount", "size"),
)
print(summary)
# 5. 处理缺失值:填 0 或整行丢弃
df["amount"] = df["amount"].fillna(0)
clean = df.dropna()
# 6. 多表合并:把用户信息拼到订单上(类似 SQL 的 LEFT JOIN)
users = pd.read_csv("users.csv")
merged = df.merge(users, on="user_id", how="left")其中 groupby 是最值得反复练习的一个:数据分析里"按某列分组、对另一列求均值/求和/计数"是最常见的统计套路,学会它和 merge,就等于拿到了 SQL 世界里 GROUP BY 和 JOIN 的钥匙。
一个完整的清洗例子
下面这段模拟一份有脏数据的销售表,把去重、填补、剔除异常、类型转换四件事走一遍:
import pandas as pd
import numpy as np
raw = pd.DataFrame({
"地区": ["华东", "华北", "华南", "华东", "华北", "华北"],
"销售额": [1500.0, 2300.0, np.nan, 1800.0, 0.0, 2300.0],
"订单日期": ["2026-01-01", "2026-01-02", "2026-01-03",
"2026-01-04", "2026-01-05", "2026-01-02"],
})
df = raw.drop_duplicates()
df["销售额"] = df["销售额"].fillna(df["销售额"].median())
df = df[df["销售额"] > 0]
df["订单日期"] = pd.to_datetime(df["订单日期"])
print(df)几个细节值得记一下。缺失值用中位数而不是均值填充,是因为中位数更抗异常值。日期列转成 datetime 之后,才能按年、按月、按周去聚合。这些看起来不起眼的动作,往往决定了后面的分析结果靠不靠谱。
五、2026 年的新变化:pandas 3.0 你必须知道的事
pandas 3.0 于 2026 年 1 月 21 日正式发布,是这个库十年来最大的一次行为调整。网上大量教程还停留在 2.x 时代,照着抄容易踩坑。下面这张表覆盖了最关键的几处改动:
| 改动 | 影响 | 应对方式 |
|---|---|---|
| 写时复制(Copy-on-Write)成为默认且唯一的模式 | 链式赋值不再修改原表 | 改数据一律用 loc 显式赋值 |
| 字符串默认使用专用 str 类型 | 不再是 object 类型 | 判断类型时改用 is_string_dtype() |
| 日期默认精度改为微秒 | 不再是纳秒 | 需要更高精度时显式指定 |
| 时区改用标准库 zoneinfo | pytz 变成可选项 | 直接传 IANA 时区名 |
新增 pd.col() 表达式语法 | 写法更接近表达式风格 | 按需使用 |
写时复制:最重要的变化
任何切片、筛选得到的结果,都不再和原表共享内存。以前改切片可能顺手把原表也改了(还会弹出一堆警告),现在两者彻底独立,行为更符合直觉;代价是老的链式赋值写法彻底失效。
import pandas as pd
df = pd.DataFrame({"name": ["张三", "李四"], "score": [80, 90]})
# 字符串列默认是 str 类型,不再是 object
print(df["name"].dtype)
# Copy-on-Write:改切片不会影响原表
sub = df[df["score"] > 85]
sub.loc[1, "score"] = 100 # 只改 sub,df 不受影响
# 链式赋值在 3.0 里不再生效,属于错误写法:
# df[df["score"] > 85]["score"] = 100
# 正确写法:用 loc 一次性定位行和列
df.loc[df["score"] > 85, "score"] = 100判断字符串列类型时,老教程里的 dtype == object 写法会失效,要改用 pd.api.types.is_string_dtype()。
时区与日期更现代
时区默认改用 Python 标准库的 zoneinfo,老牌 pytz 变成可选项;日期解析不再强制纳秒精度,会智能推断单位。
官方给的升级建议是:先把 2.3 版本下所有 FutureWarning 警告消干净,再升 3.0,迁移会平滑得多。环境方面要求 Python 不低于 3.11,NumPy 不低于 1.26,推荐同时安装 PyArrow 以启用高性能字符串。
六、可视化:让数据开口说话
分析做到最后都要落到图上。入门推荐顺序是:先用 pandas 自带的 plot 快速出图,再上 seaborn 画统计图,需要交互和网页展示时换 plotly。
不同的图解决的问题不一样。折线看趋势,柱状看对比,散点看相关性,直方图看分布,箱线图看异常值。先想清楚要表达什么,再决定画什么。
import matplotlib.pyplot as plt
# 中文乱码处理:Windows 用微软雅黑,macOS 换成 PingFang SC
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei", "PingFang SC", "SimHei"]
plt.rcParams["axes.unicode_minus"] = False
# 接着第四节的分组结果直接画
summary["avg_amount"].plot(kind="bar", title="各城市平均订单金额")
plt.ylabel("金额(元)")
plt.tight_layout()
plt.show()如果想让柱子带上数值标签,可以这样写:
regions = ["华东", "华北", "华南", "西南"]
totals = [20200, 14600, 16300, 12500]
plt.figure(figsize=(8, 5))
bars = plt.bar(regions, totals, color="#4C72B0")
plt.title("各区域销售额对比")
plt.xlabel("区域")
plt.ylabel("销售额")
for bar, value in zip(bars, totals):
plt.text(bar.get_x() + bar.get_width() / 2, value,
str(value), ha="center", va="bottom")
plt.tight_layout()
plt.show()新手画图最大的坑是中文变成方框,根因是默认字体里没有中文字形,把上面那两行字体配置加上就能解决,能少走一天弯路。
七、数据一大就卡?认识新三样:Polars、DuckDB、Arrow
Polars:把多核 CPU 用满
pandas 是单线程的,Polars 用 Rust 重写底层,自动调动全部 CPU 核心,官方形容其并行能力为"过分并行"。实测基础操作通常快 5 到 10 倍,部分基准能到 10 到 100 倍,内存占用也从 pandas 的 5 到 10 倍原始体积降到 2 到 4 倍。
它的惰性求值会先记录你的操作步骤、自动优化执行顺序,最后才一次性计算:
import polars as pl
import duckdb
# Polars:惰性求值,先声明操作,collect 时才真正计算
result = (
pl.scan_csv("big.csv")
.filter(pl.col("amount") > 100)
.group_by("city")
.agg(pl.col("amount").mean())
.collect()
)
print(result)
# DuckDB:不建库,直接用 SQL 查询 CSV 或 Parquet 文件
df = duckdb.sql("""
SELECT city, AVG(amount) AS avg_amount
FROM 'big.csv'
GROUP BY city
""").df()
print(df)有个坑要说清楚:Polars 的 group_by 和 pandas 的 groupby 名字看着像,行为并不完全一样,聚合后的列名、布尔索引的写法都有差别。拿 pandas 的思路去写 Polars,代码能跑,但性能和心智都对不上。
DuckDB:分析界的 SQLite
DuckDB 是一个嵌入进程内的分析型数据库,不需要安装和启动服务,装上库就能用 SQL 直接查询 CSV、Parquet 文件,天生为分析型查询优化。有基准测试显示 Polars 配合 DuckDB 处理亿级数据能比传统方案快 10 倍。会 SQL 的人用它几乎零学习成本。
什么时候该换工具
简单的判断标准:
- 数据在几十万行以内,pandas 最省心
- 百万到千万行、或者经常内存吃紧,换 Polars
- 数据已经是 Parquet 大文件、自己又习惯 SQL 思维,上 DuckDB
三者底层都在向 Apache Arrow 的内存格式靠拢,互相转换的成本越来越低,混着用是 2026 年的常态。新手上来的重点还是 pandas,它在小数据上的容错性和功能完整度,短期内很难被替代。等真的被内存卡住了,再换工具也不迟。
八、从入门到精通:一份可以照着走的学习路线
第一阶段:基础语法(约两到四周)
变量、列表、字典、条件、循环、函数过一遍,不求深,只求能读懂、能改。顺便花几天理解 NumPy 的数组和向量化思想,建立"用整列数据思考"的习惯。
scores = {"语文": 88, "数学": 92, "英语": 79}
total = sum(scores.values())
average = total / len(scores)
for subject, score in scores.items():
if score >= 90:
print(f"{subject} 表现优秀,得分 {score}")
print(f"总分 {total},平均分 {average:.1f}")有一类学习者会反复刷语法课,看完几十个小时的视频,关掉电脑还是写不出几行。看懂和写出来是两件事,学完上面那几个知识点,就该直接进数据处理的环节。装饰器、生成器、元类这些,前期基本用不到,先放一边。
第二阶段:NumPy 与 pandas(约三到四周)
这是投入产出比最高的阶段。把第四节的六件事练到不假思索:选择、过滤、新列、groupby、缺失值、merge,再补充时间序列的 resample 和字符串的 str 方法。练到看见一份表格,脑子里能直接冒出对应的代码。
配合第五节的 3.0 新行为,直接在最新版本上练习,避免学成旧习惯。
第三阶段:可视化与统计(约两到三周)
学 matplotlib 基础图形和 seaborn 的分布图、箱线图,同时补一点统计常识:均值、中位数、标准差、分布、相关性。图上一条陡升的线,背后到底是真实变化还是随机波动,决定了结论站不站得住。
第四阶段:完整项目(约一个月)
从公开数据集里挑一个感兴趣的题目,把提问、取数、清洗、分析、可视化、总结整条链路自己走一遍。推荐几个方向:分析自己的记账或运动数据、公开的电影评分数据集 MovieLens、Kaggle 上的泰坦尼克入门赛。完整的链路走两遍,胜过看十篇教程。中途报错、数据对不上、结论推翻重来,这些都很正常,也正是知识变成能力的地方。
第五阶段:按方向深耕(长期)
到这里路线会分岔。偏业务,就补 SQL 和 BI 工具;偏技术,就学 Polars、DuckDB、Parquet 列式存储和机器学习。代码变多之后,学习把 Notebook 里的探索整理成可复用的脚本和函数。不用同时抓几个方向,先扎进一个。
九、常见弯路与避坑建议
- 不要用 for 循环逐行处理 DataFrame。
iterrows会比向量化慢几十倍,先想"这一列整体怎么算",apply只作为最后的兜底。 - 不要在旧习惯里对切片赋值。到了 pandas 3.0 会静默失效,程序不报错,结果却是错的。
- 不要混着版本学。确认自己装的是 pandas 3.0,遇到行为和老教程不一致时,先查是不是 Copy-on-Write 或 str 类型引起的。
- 数据没清洗就拿去分析,结论自然站不住。
- 中文图表不设字体,显示成一个个方框。
- 内存爆掉先看数据类型。数字列用更小的类型(比如 int32)、重复文本列转 category,常常能省一半内存。
- 几千万行数据硬塞进 pandas,等到内存爆掉才想起来换工具。
- 不要囤课囤书。数据分析是动手技能,卡在一个真实数据集上查文档解决,比按顺序看完一门大课有效得多。
- 只顾着学工具,不理解业务和统计,算出来的结论没法用。
顺带提一句 SQL 和 pandas 的思维是互通的:GROUP BY 对应 groupby,JOIN 对应 merge,WHERE 对应布尔过滤,会一个另一个学起来很快。
十、从分析走向预测
当你想从"发生了什么"走到"可能会怎样",就到了机器学习的地盘。scikit-learn 的 API 设计非常一致,几乎所有模型都遵循拟合、预测、评估这三步。
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(n_estimators=200, random_state=42)
model.fit(X_train, y_train)
predictions = model.predict(X_test)
print("模型得分:", model.score(X_test, y_test))2026 年的 scikit-learn 在 1.8 版本里开始原生支持数组 API 标准,能把计算放到 GPU 上,处理大规模数据更顺手。不过对多数人来说,把清洗和统计做扎实,比会调模型重要得多。
另一个变化是,用大模型辅助写代码已经成了日常。写不出的逻辑、看不懂的报错,直接问,效率高很多。但要守住一条底线:得看得懂它给的每一行,能判断对错。只会复制粘贴,等于没学。
结语
数据分析的学习曲线是"入门平、进阶陡、精通靠实战":第一周就能写出有用的统计代码,但真正的功力体现在面对脏乱数据时的耐心和对业务问题的理解上。
工具会一直更新,2026 年的 pandas 3.0、Polars、DuckDB 未必是终局。底层那套东西反倒不太会变:把数据弄干净,用看得懂的图把结论讲明白,最后给出能落地的建议。路线挑一条,从手头的一份表格开始,比什么都强。
参考资料与延伸阅读
- pandas 官方文档:https://pandas.pydata.org/docs/
- pandas 3.0 更新说明:https://pandas.pydata.org/docs/whatsnew/v3.0.0.html
- Polars 官方文档:https://docs.pola.rs/
- DuckDB 官方文档:https://duckdb.org/docs/
- scikit-learn 官方文档:https://scikit-learn.org/
- Matplotlib 文档:https://matplotlib.org/
- marimo 笔记本:https://marimo.io/
- 练习数据集与竞赛:Kaggle
- 国内数据竞赛平台:阿里天池
- 环境发行版:Anaconda 下载