Skip to content

Jupyter Notebook: 交互式计算的瑞士军刀

Jupyter Notebook 是一个开源的、基于 Web 的交互式计算环境,它允许用户创建和共享包含实时代码、方程式、可视化和叙述性文本的文档。它已成为数据科学、机器学习、科学计算和学术教育领域中不可或缺的工具。

参考资料:


1. 什么是 Jupyter Notebook?

你可以将 Jupyter Notebook 想象成一个数字化的、可执行的实验笔记本。与传统的集成开发环境(IDE)一次性运行整个脚本不同,Jupyter 允许你将代码分解成一个个独立的单元格 (Cell),然后可以独立地、按任意顺序运行这些单元格。

这种交互性使得它非常适合进行探索性数据分析、快速原型设计和教学演示。


2. 核心组成部分

一个完整的 Jupyter 系统由三个主要部分组成:

  1. Web 应用程序 (The Web Application)

    • 这是你在浏览器中看到的、用于编写和运行代码的用户界面。它提供了一个文件浏览器和用于创建、编辑和运行 Notebook 文档 (.ipynb 文件) 的交互界面。
  2. 内核 (Kernels)

    • 此部分将被重构并移至下方新章节。
  3. Notebook 文档 (.ipynb)

    • 你创建的每一个 Notebook 都是一个以 .ipynb 为扩展名的文件。
    • 它本质上是一个 JSON 文件,里面以结构化的方式存储了你所有的内容,包括代码单元格、Markdown 单元格、每个单元格的输出、图像、以及元数据。这种格式使得 Notebook 文档易于通过版本控制(如 Git)进行分享和协作。

Jupyter 与 Python 的关系及核心原理

理解 Jupyter 和 Python 的关系,关键在于理解内核 (Kernel) 的概念。

Jupyter 本身是一个与语言无关的平台。它提供的是一个通用的、允许用户通过浏览器与代码执行环境进行交互的"外壳"或"界面"。而真正负责在后台执行代码的,是内核

IPython 内核:Jupyter 的 "Python 引擎"

当你选择运行 Python 代码时,Jupyter 启动的内核就是 IPython (Interactive Python)

  • IPython 不是普通的 Python:它是一个增强版的 Python 交互式解释器,提供了许多标准 Python REPL 所不具备的强大功能,例如:

    • 丰富的代码补全(Tab 键)。
    • 对象内省(在变量后加 ? 查看帮助)。
    • 魔法命令 (Magic Commands):以 %%% 开头的特殊命令,用于控制 Notebook 的行为,如 %matplotlib inline 用于在 Notebook 中直接显示 Matplotlib 图表。
    • 与系统 Shell 的无缝集成。
  • 关系总结:Jupyter 是前台的舞台,而 IPython 内核是后台的 Python 主演。你通过 Jupyter 的界面输入指令,Jupyter 将这些指令传递给 IPython 内核,IPython 内核执行后,再将结果(文本、数字、图表等)返回给 Jupyter 界面进行展示。

核心原理:解耦的通信协议

Jupyter 前端(浏览器)和后端内核之间的通信是完全解耦的,它们通过一个定义良好的、基于 ZeroMQJupyter 消息传递协议 (Jupyter Messaging Protocol) 进行交流。

这个过程就像这样:

  1. 你在代码单元格中输入 print("Hello") 并按下 Shift + Enter
  2. Jupyter Web 应用将这段代码打包成一个符合协议的 execute_request 消息。
  3. 这个消息通过网络发送给正在运行的 IPython 内核。
  4. IPython 内核接收到消息,执行代码,并将 print 函数的输出捕获。
  5. 内核将这个输出打包成一个 stream 消息,再通过网络发回给前端。
  6. Jupyter Web 应用接收到消息,并将其渲染在代码单元格的下方。

这种架构的优美之处在于,只要一个编程语言能实现一个遵循此消息协议的内核,它就能无缝地接入 Jupyter 生态系统。这就是为什么 Jupyter 能支持 R、Julia、Scala 等众多语言的原因——它们都有自己的内核实现。


3. 核心概念:单元格 (Cells)

单元格是 Notebook 的基本构建块。主要有两种类型:

代码单元格 (Code Cells)

  • 这是你编写和执行代码的地方。
  • 每个代码单元格前面都有一个 In [ ]: 标记。当你运行这个单元格时(通过点击 "Run" 按钮或使用快捷键 Shift + Enter),代码会被发送到内核执行。
  • 如果代码有输出(例如 print() 语句的结果,或是一个变量的最后一行),输出会直接显示在该代码单元格的下方。
  • 运行过的单元格,其前面的方括号会填上一个数字,表示其执行顺序。
python
# 这是一个代码单元格
import numpy as np

def square(x):
    return x * x

x = np.random.randint(1, 10)
y = square(x)

print(f'{x} 的平方是 {y}')

Markdown 单元格 (Markdown Cells)

  • 这是你施展"文学编程 (Literate Programming)"才华的地方。

  • 你可以在这些单元格中使用 Markdown 语法来编写格式丰富的叙述性文本,包括:

    • 标题
    • 粗体、斜体文本
    • 列表(有序或无序)
    • 链接和图片
    • 表格
    • 甚至是 LaTeX 数学公式
  • 这使得你能够清晰地记录你的思考过程、解释代码的逻辑、展示分析结果,让整个 Notebook 成为一个完整的、自解释的故事。

markdown
# 这是一个 Markdown 单元格

## 实验目的
本次实验旨在验证 `square` 函数的正确性。

- 我们将生成一个随机数。
- 然后计算它的平方。

最终结果应符合预期:$x^2 = y$。

4. 为何如此受欢迎?

  • 交互式探索: 允许你快速迭代和实验,非常适合数据清洗、模型调整等需要不断试错的任务。
  • 结果与代码一体: 计算结果(包括图表和表格)会内联显示在代码下方,使得分析流程一目了然。
  • 文学编程: 将代码、解释和可视化结合在一起,极大地增强了工作的可读性和可复现性。
  • 易于分享: .ipynb 文件可以轻松地通过 GitHub、NBViewer 等平台分享,他人无需安装任何东西就能在浏览器中查看你的完整工作。

5. 如何开始?

最简单的方式是使用 pip 安装 JupyterLab (Jupyter Notebook 的下一代界面)。

bash
# 确保你已经在一个虚拟环境中
pip install jupyterlab

# 启动 JupyterLab 服务
jupyter lab

执行最后一条命令后,你的默认浏览器会自动打开一个新标签页,显示 JupyterLab 的界面,你就可以开始创建你的第一个 Notebook 了!

推荐的安装方式:使用 pipx

虽然直接用 pip 安装很方便,但一个更健壮、更推荐的长期策略是使用 pipx 来安装 JupyterLab。

核心理念:将 JupyterLab 视为一个系统级的应用程序(就像你的代码编辑器或浏览器一样),而不是每个项目都需要的

为什么这样更好?

  • 保持环境干净:你不需要在每个项目的虚拟环境 (venv) 中都重复安装 JupyterLab 及其大量的依赖。你的项目环境可以只包含项目本身需要的库(如 pandas, requests)。
  • 单一入口点:无论你在哪个项目中工作,你使用的都是同一个、由 pipx 统一管理的 JupyterLab 实例。
  • 避免依赖冲突:JupyterLab 本身的依赖被 pipx 安全地隔离起来,绝不会与你任何项目的依赖发生冲突。

工作流:全局应用 + 项目内核

这种模式分为两步:

第一步:使用 pipx 一次性安装 JupyterLab

bash
# 1. 安装 pipx (如果尚未安装)
python -m pip install --user pipx
python -m pipx ensurepath

# 2. 使用 pipx 安装 jupyterlab
pipx install jupyterlab

完成这一步后,jupyter lab 就成了一个你可以在系统任何地方调用的全局命令。

第二步:为你的项目创建独立内核

现在,对于你每一个具体的数据科学项目,你都应该创建一个独立的虚拟环境,并在其中注册一个内核。

bash
# 1. 为你的新项目创建并激活虚拟环境
cd /path/to/my_new_project/
python -m venv .venv
source .venv/bin/activate

# 2. 在这个环境中安装项目所需的库
pip install pandas matplotlib scikit-learn

# 3. 安装 ipykernel,它是连接你的环境和 Jupyter 的桥梁
pip install ipykernel

# 4. 将当前虚拟环境注册为一个新的 Jupyter 内核
#    --name: 内核的内部名称
#    --display-name: 在 Jupyter 界面上显示的美观名称
python -m ipykernel install --user --name="my_new_project_kernel" --display-name="Python (My New Project)"

现在,当你运行全局的 jupyter lab 命令后,在新建 Notebook 的启动器 (Launcher) 页面,你就能在内核选择器中看到 "Python (My New Project)" 这个选项了。选择它,这个 Notebook 就会运行在你为 my_new_project 创建的、包含 pandas 等库的干净环境中。

当你完成了这个项目,可以轻松地移除这个内核:

bash
jupyter kernelspec uninstall my_new_project_kernel

这种"全局Jupyter + 本地内核"的模式,是目前公认的、管理复杂 Python 项目时最清晰、最不容易出错的最佳实践。