摘要
一个稳定的数据分析环境,应该能够重复安装、快速验证、方便调试,并且可以从临时探索逐步过渡到可维护的项目代码。本文从 Python 版本、虚拟环境、Jupyter、NumPy 和 pandas 开始,搭建一个适合数据分析学习与项目开发的基础环境。
文章还会通过一个销售数据示例,演示如何创建 DataFrame、查看数据结构、执行筛选和统计,并介绍 Notebook 与 .py 文件的分工、依赖文件管理和常见环境问题。
一、背景与问题
很多数据分析脚本无法复用,并不是分析逻辑本身有问题,而是环境和代码没有建立边界:
- 直接使用系统 Python,多个项目的依赖互相冲突。
- 在 Notebook 中反复执行单元格,变量状态与执行顺序不透明。
- 没有记录依赖版本,换一台电脑后无法复现。
- 把所有处理逻辑写在一个 Notebook 中,后续很难测试和调度。
- 数据文件、代码、图表和临时结果混在同一个目录。
一个合理的基础环境应当满足:
text
项目目录
├─ 虚拟环境
├─ Notebook 探索
├─ src 可复用代码
├─ data 原始数据与处理结果
├─ tests 测试代码
└─ requirements / pyproject 依赖声明
Notebook 适合快速观察数据和验证想法,Python 模块适合复用、测试和自动化。两者应该协同使用,而不是互相替代。
二、核心概念
1. Python 解释器与虚拟环境
Python 解释器负责执行代码。虚拟环境则为一个项目创建独立的包安装目录,避免不同项目之间共享同一套依赖。
常见选择如下:
| 工具 | 适用场景 |
|---|---|
venv |
Python 内置,轻量、适合大多数项目 |
uv |
依赖安装和环境创建速度快,适合现代项目 |
| Conda | 需要管理 Python 之外的科学计算依赖 |
| Poetry | 需要完整项目依赖和发布管理 |
初学阶段使用 venv 已经足够,团队项目可以根据现有工程规范选择统一工具。
2. Jupyter Notebook 与 JupyterLab
Notebook 由多个可执行单元组成,每个单元可以包含代码、结果和说明文字。JupyterLab 在 Notebook 基础上提供文件浏览器、终端和多个文档窗口,更适合项目化探索。
Notebook 的优势:
- 可以分步执行和查看中间结果。
- 适合绘制图表和记录分析过程。
- 便于快速验证数据假设。
Notebook 的风险:
- 单元格执行顺序可能与显示顺序不同。
- 隐藏变量会影响结果。
- 不适合作为复杂业务流程的唯一实现。
3. NumPy 与 pandas
NumPy 提供多维数组和向量化计算,pandas 提供面向表格数据的 Series 和 DataFrame。
text
Python
└─ NumPy:数组、数值计算、向量化
└─ pandas:表格、索引、分组、合并、时间序列
数据分析中的大量操作都建立在这两个库之上。
4. DataFrame 的基本结构
DataFrame 是带有行索引和列名的二维数据结构:
| name | department | amount |
|---|---|---|
| Alice | sales | 1200 |
| Bob | support | 800 |
每一列可能拥有不同的数据类型,但同一列通常需要保持类型一致,才能正确执行排序、聚合和比较。
三、工作原理
1. 环境创建流程
text
安装 Python
↓
创建项目目录
↓
创建虚拟环境
↓
安装分析依赖
↓
注册 Jupyter Kernel
↓
运行最小验证代码
每个项目都应在虚拟环境中安装依赖。系统 Python 只负责创建环境和运行基础工具。
2. Notebook Kernel
Jupyter 页面本身只是交互界面,真正执行代码的是 Kernel。一个常见问题是页面显示的 Python 环境与实际 Kernel 不一致,导致"明明安装了包却无法导入"。
因此,创建虚拟环境后需要把它注册为一个明确命名的 Kernel:
text
项目环境: data-analysis
Jupyter Kernel: Python (data-analysis)
3. 数据分析的最小闭环
一个可重复的分析过程至少包含:
- 读取数据。
- 检查行数、列名和类型。
- 处理明显的数据质量问题。
- 执行统计或筛选。
- 输出结果和验证信息。
不要一开始就直接计算指标。先确认数据结构和数据质量,能够减少大量误判。
四、实战示例
1. 创建项目目录
PowerShell 示例:
powershell
New-Item -ItemType Directory -Path sales-analysis
Set-Location sales-analysis
New-Item -ItemType Directory -Path notebooks,src,data,tests,output
python -m venv .venv
.\.venv\Scripts\Activate.ps1
如果 PowerShell 禁止执行激活脚本,可以直接调用虚拟环境中的 Python,或者根据本机安全策略调整执行方式。不要为了激活环境而关闭系统级安全策略。
2. 安装依赖
powershell
python -m pip install --upgrade pip
python -m pip install numpy pandas matplotlib jupyterlab openpyxl
python -m pip freeze > requirements.txt
使用 python -m pip 可以减少系统中存在多个 pip 命令时的解释器混淆。
3. 注册 Jupyter Kernel
powershell
python -m ipykernel install --user --name data-analysis --display-name "Python (data-analysis)"
jupyter lab
打开 JupyterLab 后,在 Notebook 中选择 Python (data-analysis) Kernel。
4. 创建示例数据
python
from pathlib import Path
import pandas as pd
data_dir = Path("data")
data_dir.mkdir(exist_ok=True)
sales = pd.DataFrame(
{
"order_id": ["A001", "A002", "A003", "A004"],
"department": ["华东", "华南", "华东", "华北"],
"amount": [1200.0, 800.0, 1560.0, 620.0],
"order_date": [
"2026-09-01",
"2026-09-02",
"2026-09-03",
"2026-09-03",
],
}
)
sales.to_csv(data_dir / "sales.csv", index=False, encoding="utf-8-sig")
5. 读取并检查数据
python
import pandas as pd
df = pd.read_csv("data/sales.csv")
print(df.head())
print(df.shape)
print(df.dtypes)
print(df.isna().sum())
print(df.describe(numeric_only=True))
head() 用来查看样本,shape 查看规模,dtypes 检查类型,isna() 检查缺失值,describe() 查看数值列的基础统计。
6. 类型转换与基本统计
python
df["order_date"] = pd.to_datetime(df["order_date"])
department_summary = (
df.groupby("department", as_index=False)
.agg(
order_count=("order_id", "nunique"),
total_amount=("amount", "sum"),
average_amount=("amount", "mean"),
)
.sort_values("total_amount", ascending=False)
)
print(department_summary)
日期列转换为 datetime 后,才能方便地进行按月、按周和按日期范围统计。
7. 将探索逻辑整理为函数
python
from pathlib import Path
import pandas as pd
def load_sales(path: str | Path) -> pd.DataFrame:
frame = pd.read_csv(path)
frame["order_date"] = pd.to_datetime(frame["order_date"], errors="coerce")
frame["amount"] = pd.to_numeric(frame["amount"], errors="coerce")
return frame
def summarize_by_department(frame: pd.DataFrame) -> pd.DataFrame:
return (
frame.dropna(subset=["department", "amount"])
.groupby("department", as_index=False)
.agg(
order_count=("order_id", "nunique"),
total_amount=("amount", "sum"),
)
.sort_values("total_amount", ascending=False)
)
当代码需要被重复执行时,应尽早从 Notebook 单元格中提取为函数,再由 Notebook 调用函数查看结果。
8. 生成分析结果
python
summary = summarize_by_department(load_sales("data/sales.csv"))
summary.to_csv("output/department_summary.csv", index=False, encoding="utf-8-sig")
print("result rows:", len(summary))
输出目录只保存可交付结果,临时中间文件应单独放置或在任务结束后清理。
五、常见问题与实践建议
1. ModuleNotFoundError
先检查当前解释器:
python
import sys
print(sys.executable)
再确认包是否安装在同一个环境:
powershell
python -m pip show pandas
如果 Jupyter Kernel 使用的是另一个 Python,需要重新选择 Kernel 或重新注册环境。
2. Notebook 结果为什么不稳定?
常见原因是单元格执行顺序混乱、变量被重复覆盖或依赖了隐藏状态。提交 Notebook 前,建议执行"重启 Kernel 并从头运行全部单元格",确认结果可以在干净环境中复现。
3. 什么时候应该使用 .py 文件?
以下情况应优先使用模块或脚本:
- 逻辑需要被多个 Notebook 或任务复用。
- 需要编写单元测试。
- 需要定时运行或部署。
- 处理流程较长,包含多个步骤和异常分支。
Notebook 负责探索和展示,.py 文件负责稳定执行。
4. 文件编码导致中文乱码怎么办?
读取和输出 CSV 时明确指定编码。Windows 环境中,utf-8-sig 对 Excel 的兼容性通常更好;跨平台数据交换优先统一使用 UTF-8,并在团队中明确约定。
5. 为什么不建议把数据文件提交到代码仓库?
原始数据可能包含敏感信息,体积也可能较大。应通过 .gitignore 排除本地数据,并在仓库中提供脱敏样例和数据字典。
六、进阶思考
1. 用 pyproject.toml 管理项目
当项目从探索进入长期维护阶段,可以把依赖、工具配置和项目元数据统一放到 pyproject.toml。无论使用 uv、Poetry 还是其他工具,核心目标都是让环境创建和依赖升级可追踪。
2. 数据目录分层
建议区分:
text
data/
├─ raw/ 原始数据,只读保存
├─ interim/ 中间处理结果
├─ processed/ 可供分析的数据集
└─ sample/ 脱敏样例数据
原始数据不覆盖,中间结果有明确命名,最终结果包含生成时间或版本信息。
3. 让分析流程可验证
后续可以加入:
- 数据行数和列名断言。
- 金额非负校验。
- 主键唯一性检查。
- 日期范围检查。
- 输出文件存在性检查。
- 对关键聚合结果编写测试。
数据分析不是"只要能运行就算正确",关键结果需要有验证条件。
结论
一个可持续的数据分析环境,需要同时解决 Python 解释器、虚拟环境、Jupyter Kernel、依赖版本和项目目录结构问题。NumPy 负责数组计算,pandas 负责表格数据,Notebook 负责探索,Python 模块负责复用和自动化。
完成环境搭建后,下一步应学习 NumPy 的数组、索引、形状变换和向量化运算,再逐步进入 pandas 数据结构、读取和清洗。
参考资料
- Python 官方文档:https://docs.python.org/3/
- NumPy 官方文档:https://numpy.org/doc/
- pandas 官方文档:https://pandas.pydata.org/docs/
- Jupyter 官方文档:https://docs.jupyter.org/