Jupyter Notebook 是一个开源的交互式计算环境,它允许你创建和共享包含实时代码、方程、可视化图表和叙述性文本的文档。自 2014 年从 IPython 项目分离以来,Jupyter 已成为数据科学、机器学习、科学计算和教育领域不可或缺的工具。
原始内容保留:
Jupyter 支持多种安装方式,根据你的使用场景选择最适合的方案:
# 基础安装
pip install jupyter
# 包含常用科学计算库
pip install jupyter numpy pandas matplotlib
# 使用 requirements.txt 管理依赖
cat > requirements.txt << 'EOF'
jupyter==7.0.0
numpy==1.24.0
pandas==2.0.0
matplotlib==3.7.0
scikit-learn==1.3.0
EOF
pip install -r requirements.txt
# 创建独立环境
conda create -n jupyter-env python=3.11
conda activate jupyter-env
# 安装 jupyter 及相关库
conda install jupyter numpy pandas matplotlib
# 或者使用 environment.yml
cat > environment.yml << 'EOF'
name: jupyter-env
channels:
- conda-forge
- defaults
dependencies:
- python=3.11
- jupyter=7.0
- numpy=1.24
- pandas=2.0
- matplotlib=3.7
- scikit-learn=1.3
EOF
conda env create -f environment.yml
# 拉取官方镜像
docker pull jupyter/scipy-notebook:latest
# 运行容器
docker run -p 8888:8888 \
-v $(pwd):/home/jovyan/work \
jupyter/scipy-notebook:latest
# 带密码运行
docker run -p 8888:8888 \
-e JUPYTER_TOKEN=your-secure-token \
-v $(pwd):/home/jovyan/work \
jupyter/scipy-notebook:latest
Hugo 踩坑记录:在服务器上使用 Docker 部署时,注意挂载卷的权限问题。Jupyter 容器默认使用
jovyan用户(UID 1000),如果宿主机目录权限不对,会导致无法保存文件。解决方案:# 使用 --user root 或调整宿主机目录权限 docker run -p 8888:8888 --user root \ -e CHOWN_HOME=yes \ -v $(pwd):/home/jovyan/work \ jupyter/scipy-notebook:latest
# 基本启动
jupyter notebook
# 指定端口和目录
jupyter notebook --port 9999 --no-browser --ip=0.0.0.0
# 后台运行(生产环境)
nohup jupyter notebook --ip=0.0.0.0 --port=8888 --no-browser > jupyter.log 2>&1 &
# 生成配置文件
jupyter notebook --generate-config
# 配置文件位置:~/.jupyter/jupyter_notebook_config.py
# ~/.jupyter/jupyter_notebook_config.py
c.NotebookApp.ip = '0.0.0.0' # 允许远程访问
c.NotebookApp.port = 8888
c.NotebookApp.open_browser = False
c.NotebookApp.notebook_dir = '/path/to/your/notebooks'
# 设置密码(避免使用 token)
# 生成密码哈希:jupyter notebook password
# 或手动设置:
from notebook.auth import passwd
c.NotebookApp.password = passwd('your-password')
# 启用 HTTPS
c.NotebookApp.certfile = '/path/to/cert.pem'
c.NotebookApp.keyfile = '/path/to/key.pem'
Jupyter 采用客户端-服务器架构:
┌─────────────────┐ HTTP/WebSocket ┌─────────────────┐
│ 浏览器 (Client) │ ═══════════════════► │ Jupyter Server │
│ (Notebook UI) │ │ (Tornado) │
└─────────────────┘ └────────┬────────┘
│
│ ZeroMQ
▼
┌─────────────────┐
│ Kernel (Python) │
│ (代码执行引擎) │
└─────────────────┘
核心组件:
| 组件 | 职责 | 技术栈 |
|---|---|---|
| Notebook Server | HTTP 服务器、WebSocket 管理、文件服务 | Tornado |
| Kernel | 代码执行、状态管理、结果返回 | IPython / 其他语言 |
| Notebook Document | .ipynb 文件格式(JSON) |
JSON Schema |
| Frontend | 用户界面、单元格管理 | JavaScript / React |
Notebook 文件本质是 JSON,包含以下结构:
{
"metadata": {
"kernelspec": {"name": "python3", "display_name": "Python 3"},
"language_info": {"name": "python", "version": "3.11.0"}
},
"nbformat": 4,
"nbformat_minor": 5,
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": ["# 标题\\n", "正文内容"]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"source": ["print('Hello')"],
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": ["Hello\\n"]
}
]
}
]
}
Hugo 经验:
.ipynb文件适合版本控制,但 diff 可读性差。建议配合nbstripout工具自动清除输出后再提交:pip install nbstripout nbstripout --install # 在当前 git 仓库安装钩子
启动后浏览器自动打开(或使用 --no-browser 后手动访问):
http://localhost:8888/tree
界面分为三个主要区域:
.ipynb 文件和文件夹Jupyter 有两种模式:
| 模式 | 进入方式 | 用途 |
|---|---|---|
| 命令模式(蓝色边框) | Esc |
操作单元格本身 |
| 编辑模式(绿色边框) | Enter |
编辑单元格内容 |
| 快捷键 | 功能 |
|---|---|
A |
上方插入单元格 |
B |
下方插入单元格 |
DD |
删除单元格 |
Y |
转为代码单元格 |
M |
转为 Markdown 单元格 |
R |
转为原始文本单元格 |
Shift + Enter |
运行并跳到下一单元格 |
Ctrl + Enter |
运行并停留在当前单元格 |
Alt + Enter |
运行并在下方插入新单元格 |
Shift + M |
合并选中单元格 |
Ctrl + Shift + - |
在光标处分割单元格 |
| 快捷键 | 功能 |
|---|---|
Tab |
代码补全 / 缩进 |
Shift + Tab |
查看函数文档 |
Ctrl + / |
注释/取消注释 |
Ctrl + D |
删除整行 |
Ctrl + Shift + - |
分割单元格 |
Hugo 偏好:习惯使用
Esc+A/B快速插入单元格,Shift + Enter连续执行,DD清理无用单元格。掌握这些基础快捷键后,编辑效率提升 3 倍以上。
最常用类型,支持 Python 及 100+ 种语言内核:
# 基础代码执行
x = 10
y = 20
x + y
输出显示:
# 多输出类型示例
from IPython.display import display, HTML, Image, JSON
# 1. 文本输出
print("普通文本")
# 2. HTML 输出
display(HTML('<h3 style="color:blue">蓝色标题</h3>'))
# 3. 图片输出
# display(Image('path/to/image.png'))
# 4. JSON 输出
display(JSON({"key": "value", "number": 42}))
支持标准 Markdown + 扩展语法:
# 标题
## 二级标题
**粗体** *斜体* ~~删除线~~
- 无序列表
- [ ] 待办事项
- [x] 已完成
| 列1 | 列2 |
|-----|-----|
| A | B |
> 引用块
[链接文本](https://example.com)

`行内代码`
```python
# 代码块
print("Hello")
### 原始文本单元格(Raw Cell)
用于nbconvert 转换时保持原样,常用于:
- LaTeX 文档中的原始命令
- HTML 转换时的特殊标记
- ReStructuredText 的指令
### 单元格元数据
每个单元格可以附加元数据(View -> Cell Toolbar -> Edit Metadata):
```json
{
"tags": ["parameters", "hide-output"],
"slideshow": {
"slide_type": "slide"
}
}
常用标签:
parameters:papermill 参数化执行hide-input / hide-output:隐藏输入/输出raises-exception:预期会抛出异常Jupyter 的魔法命令以 %(行魔法)或 %%(单元格魔法)开头,是 IPython 的强大特性。
# 查看所有魔法命令
%lsmagic
# 时间测量
%time sum(range(1000000))
# 详细性能分析
%timeit -n 100 -r 5 sum(range(1000000))
# 查看变量
%who # 所有变量
%whos # 带类型信息
# 环境变量
%env PATH
# 目录操作
%cd /path/to/dir
%pwd
%ls
# 运行脚本
%run script.py
# 加载代码
%load script.py # 将文件内容加载到单元格
# 历史记录
%history -n 1-10
# 调试
%debug # 进入 pdb 调试器
# 粘贴代码(处理缩进)
%paste
%cpaste
# 测量整个单元格
%%time
import time
time.sleep(1)
print("Done")
# 编写并运行 C 代码
%%cython
# 需要安装:pip install cython
def fib(int n):
cdef int i
cdef double a=0, b=1
for i in range(n):
a, b = a+b, a
return a
# HTML 输出
%%html
<div style="background: #f0f0f0; padding: 10px;">
<h3>自定义 HTML</h3>
</div>
# JavaScript
%%javascript
alert("Hello from JS!");
# Bash 命令
%%bash
ls -la
echo "Current directory: $(pwd)"
# SQL 查询(需要安装 ipython-sql)
%%sql
SELECT * FROM users LIMIT 10;
# LaTeX
%%latex
$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$
# 写入文件
%%writefile script.py
def hello():
print("Hello, World!")
# 捕获输出
%%capture output
import warnings
warnings.warn("This is a warning")
# 之后查看
output.show()
from IPython.core.magic import register_line_magic, register_cell_magic
@register_line_magic
def hello(line):
___TRIPLE_QUOTE___自定义行魔法:打招呼___TRIPLE_QUOTE___
print(f"Hello, {line or 'World'}!")
# 使用:%hello Jupyter
@register_cell_magic
def double(cell):
___TRIPLE_QUOTE___自定义单元格魔法:打印两遍___TRIPLE_QUOTE___
print(cell)
print("---")
print(cell)
# 使用:%%double
# 任意内容
Jupyter 支持 100+ 种编程语言:
| 语言 | 内核名称 | 安装命令 |
|---|---|---|
| Python | ipykernel | pip install ipykernel |
| R | IRkernel | install.packages('IRkernel') |
| Julia | IJulia | using Pkg; Pkg.add("IJulia") |
| Scala | almond | coursier bootstrap almond |
| JavaScript | ijavascript | npm install -g ijavascript |
| Bash | bash_kernel | pip install bash_kernel |
# 查看已安装内核
jupyter kernelspec list
# 安装 Python 内核
python -m ipykernel install --user --name=myenv --display-name="Python (myenv)"
# 卸载内核
jupyter kernelspec uninstall myenv
# 内核规格文件位置
# ~/.local/share/jupyter/kernels/
# 在 Notebook 中操作内核
# 查看当前内核信息
import sys
print(sys.executable)
print(sys.version)
# 中断执行:Kernel -> Interrupt
# 重启内核:Kernel -> Restart
# 重启并清空输出:Kernel -> Restart & Clear Output
# 重启并全部运行:Kernel -> Restart & Run All
Hugo 踩坑记录:在 Jupyter 中安装包后,有时需要重启内核才能导入。这是因为内核启动时加载了环境快照,运行时安装的包不会自动生效。建议在 Notebook 开头统一安装:
!pip install package-name # 然后重启内核
# 安装扩展管理器
pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
# 启用常用扩展
jupyter nbextension enable toc2/main # 目录导航
jupyter nbextension enable collapsible_headings/main # 可折叠标题
jupyter nbextension enable codefolding/main # 代码折叠
jupyter nbextension enable execute_time/ExecuteTime # 执行时间
jupyter nbextension enable spellchecker/main # 拼写检查
jupyter nbextension enable scratchpad/main # 草稿板
# 安装 JupyterLab
pip install jupyterlab
# 启动 JupyterLab
jupyter lab
# 安装扩展(需要 Node.js)
jupyter labextension install @jupyter-widgets/jupyterlab-manager
# 常用扩展
# - jupyterlab-git: Git 集成
# - jupyterlab-drawio: 流程图绘制
# - jupyterlab-spreadsheet: 电子表格
import ipywidgets as widgets
from IPython.display import display
# 基础控件
slider = widgets.IntSlider(value=50, min=0, max=100, description='数值:')
display(slider)
# 文本输入
text = widgets.Text(value='Hello', description='文本:')
display(text)
# 下拉选择
dropdown = widgets.Dropdown(
options=['选项1', '选项2', '选项3'],
value='选项1',
description='选择:'
)
display(dropdown)
# 按钮
button = widgets.Button(description='点击我')
output = widgets.Output()
def on_button_click(b):
with output:
print(f"滑块值: {slider.value}, 文本: {text.value}")
button.on_click(on_button_click)
display(button, output)
# 复杂布局
from ipywidgets import HBox, VBox, Layout
box = VBox([
HBox([slider, text]),
dropdown,
button,
output
])
display(box)
# Matplotlib 内联显示
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x))
plt.title('正弦波')
plt.show()
# 交互式图表(plotly)
import plotly.express as px
fig = px.scatter(x=[1, 2, 3], y=[1, 4, 9])
fig.show()
# Bokeh 交互
from bokeh.plotting import figure, output_notebook, show
output_notebook()
p = figure(title="示例")
p.line([1, 2, 3], [1, 4, 9])
show(p)
pip install papermill
# 在 Notebook 中定义参数单元格(标记 tags: ["parameters"])
# 这是默认值
input_file = "data.csv"
output_dir = "results/"
threshold = 0.5
# 命令行执行并注入参数
papermill template.ipynb output.ipynb \
-p input_file "new_data.csv" \
-p threshold 0.8
# 使用 YAML 参数文件
papermill template.ipynb output.ipynb -f params.yaml
# 安装 nbimporter
pip install nbimporter
# 在其他 Notebook 中导入
import nbimporter
import my_notebook # 导入 my_notebook.ipynb
# 调用其中定义的函数
my_notebook.my_function()
# 编辑 crontab
crontab -e
# 每小时执行一次 Notebook
0 * * * * cd /path/to/notebooks && jupyter nbconvert --to notebook --execute report.ipynb --output report_$(date +\%Y\%m\%d_\%H).ipynb
# 使用 papermill 更灵活
0 9 * * * papermill daily_report.ipynb "outputs/daily_$(date +\%Y-\%m-\%d).ipynb" -f daily_params.yaml
# 转换为 Python 脚本
jupyter nbconvert --to script notebook.ipynb
# 转换为 HTML
jupyter nbconvert --to html notebook.ipynb
# 转换为 PDF(需要 LaTeX)
jupyter nbconvert --to pdf notebook.ipynb
# 转换为 Markdown
jupyter nbconvert --to markdown notebook.ipynb
# 执行并转换
jupyter nbconvert --to html --execute notebook.ipynb
# 使用模板
jupyter nbconvert --to slides notebook.ipynb # 幻灯片
jupyter nbconvert --to latex notebook.ipynb # LaTeX
# ~/.jupyter/templates/my_template.tpl
{% extends 'full.tpl' %}
{% block header %}
{{ super() }}
<style>
.container { max-width: 1200px; }
code { background: #f4f4f4; padding: 2px 4px; }
</style>
{% endblock %}
# 项目标题
> 简要描述本 Notebook 的目的
## 环境准备
- 依赖包导入
- 配置参数设置
## 数据加载
- 数据来源说明
- 加载与预处理
## 分析过程
- 分步骤展示
- 关键发现标注
## 结果输出
- 可视化图表
- 结论总结
## 附录
- 参考链接
- 版本信息
# 1. 所有导入放在开头
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 2. 配置集中管理
CONFIG = {
'data_path': './data/',
'random_seed': 42,
'figure_size': (12, 6)
}
# 3. 函数定义区
def load_data(path):
___TRIPLE_QUOTE___加载数据并返回 DataFrame___TRIPLE_QUOTE___
return pd.read_csv(path)
def preprocess(df):
___TRIPLE_QUOTE___数据预处理___TRIPLE_QUOTE___
return df.dropna()
# 4. 执行区
df = load_data(CONFIG['data_path'] + 'input.csv')
df_clean = preprocess(df)
# 方案1:使用 nbstripout 清除输出
pip install nbstripout
nbstripout --install
# 方案2:双文件策略(.ipynb + .py)
jupyter nbconvert --to script notebook.ipynb # 生成 notebook.py
# 版本控制 .py 文件,.ipynb 加入 .gitignore
# 方案3:使用 Jupytext
pip install jupytext
# 自动生成 .py 配对文件,双向同步
# 1. 大数据处理使用 Dask
import dask.dataframe as dd
ddf = dd.read_csv('large_file.csv')
# 2. 内存分析
%load_ext memory_profiler
%memit large_operation()
# 3. 代码剖析
%prun -s cumulative some_function()
# 4. 并行计算
from multiprocessing import Pool
with Pool(4) as p:
results = p.map(process_chunk, chunks)
# 查看内核进程
ps aux | grep ipykernel
# 强制终止
kill -9 <PID>
# 在 Jupyter 中:Kernel -> Restart
# 检查 Python 路径
import sys
print(sys.path)
# 检查当前内核
import os
print(os.sys.executable)
# 在当前内核安装
!{sys.executable} -m pip install package_name
# 查找占用端口的进程
lsof -i :8888
# 使用随机端口启动
jupyter notebook --port 0
# ~/.jupyter/jupyter_notebook_config.py
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.port = 8888
c.NotebookApp.open_browser = False
c.NotebookApp.allow_remote_access = True
# 安全警告:生产环境务必设置密码或 token
c.NotebookApp.password = 'sha1:...' # 使用 jupyter notebook password 生成
<!-- 确保对齐线至少有3个横线 -->
| 列1 | 列2 | 列3 |
|-----|-----|-----|
| A | B | C |
文档信息
原始内容字数:119 字
优化后字数:约 12,000 字
保留内容:原始安装链接(命令行安装、Docker 安装)
新增内容:完整的使用指南、架构说明、魔法命令、内核管理、扩展插件、高级用法、最佳实践、故障排除
适用场景:数据科学、机器学习、教学演示、快速原型开发