☰
Jupyter Notebook/Lab 使用技巧大全:从安装配置到内核管理
2026/10/8 14:50:44 网站建设 项目流程

“Jupyter Notebook/Lab使用技巧大全”这个标题看着挺老生常谈,但真到手动起服务、改配置、调插件的时候,踩的坑一个接一个。我这两年从Notebook换到JupyterLab再换回来,折腾了不少轮,把日常用得最多、最容易被忽略的系统性技巧整理一遍,从安装、配置、目录管理、内核环境到各类插件的组合玩法都涵盖,适合刚入门的数据分析师,也适合已经被PermissionError折磨过的老手。

1. 安装与启动:先把手上的环境理顺

1.1 安装方式怎么选

Jupyter的安装路径有好几条,关键看你的使用场景。如果只是普通的数据分析、机器学习调用,直接用Anaconda发行版最省事,自带Python环境和大量常用库。如果已经在用系统Python,或者不想为了一个工具安装一堆额外库,就选pip安装:

# 基础安装 pip install notebook jupyterlab # 如果需要额外功能 pip install jupyter_contrib_nbextensions pip install jupyter_nbextensions_configurator

用conda也可以,命令是conda install -c conda-forge notebook jupyterlab。我个人的建议是,别在同一个环境里同时混用conda和pip装Jupyter,容易把依赖搞乱。一个环境承担一个职责,这是后面所有流程不翻车的前提。

1.2 启动服务器、浏览器与多实例

启动Jupyter Notebook最常规的操作是命令行敲jupyter notebook,JupyterLab则是jupyter lab。默认会占用8888端口,如果8888已经被占用,它会自动切到8889、8890这样往后递推,实际运行的地址会在启动日志里显示,复制到浏览器即可。

有时候需要保持服务器在后台运行:

nohup jupyter lab --ip=0.0.0.0 --port=8888 > jupyter.log 2>&1 &

参数--ip=0.0.0.0意味着让局域网内其他机器也能访问,注意这意味着任何人都可能访问到你的界面,后面必须配上密码或者token机制,否则相当于把你的计算资源裸露在网络上。

如果只是临时查看一个同事发的notebook文件,不需要启动完整服务,可以直接用VS Code的Jupyter扩展打开,也可以用一个轻量命令:

jupyter nbconvert --to notebook --execute my_notebook.ipynb

这个命令可以重新执行一遍notebook并输出结果,适合做批量检查。

2. 配置文件与权限问题:PermissionError其实是常态

2.1 配置文件在哪,怎么改

Jupyter的配置文件默认在~/.jupyter/jupyter_notebook_config.py,第一次运行前可能不存在,需要先生成:

jupyter notebook --generate-config

在Windows上路径是C:\Users\你的用户名\.jupyter\,Linux/macOS则是/home/用户名/.jupyter/。配置文件本质上就是一个Python文件,里面一行行赋值,比如:

c.ServerApp.ip = '0.0.0.0' c.ServerApp.port = 8888 c.ServerApp.open_browser = False c.ServerApp.allow_remote_access = True

我习惯把所有自定义项集中放在文件末尾,加注释说明每一行的作用,这样半年后回来看还能秒懂。

2.2 PermissionError的成因与解决方案

热搜里频繁出现的PermissionError: [Errno 13] Permission denied,绝大多数不是Jupyter本身的问题,而是目录权限或者用户身份设置出了问题。常见场景有三种。

第一种,启动目录没有写权限。比如在/root或者系统保护目录下启动,普通用户没法写文件,解决方案是换到自己的用户目录,或者用sudo chmod调整权限。第二种,在一个用户下创建了notebook文件,再用sudo或者另一个用户去打开,文件属主变了,导致无法写入,这种情况直接chown把属主改回来。第三种最常见也最隐蔽,Windows下某些安全软件拦截了Jupyter的写入,或者OneDrive同步目录权限冲突,运行时的临时文件没法落盘,自然会报PermissionError。

排查思路应该按日志顺序来:第一看完整报错中涉及哪个文件路径,第二看当前用户对该路径是否有读写权限,第三看是否有安全软件拦截。不要一上来就重装Jupyter,那是最后手段。

# Linux/macOS下检查某个目录的权限 ls -ld /path/to/your/notebook_dir # 修改文件属主为当前用户 sudo chown -R $(whoami) /path/to/your/notebook_dir

2.3 修改默认保存路径

很多人不知道,Jupyter启动时的工作目录就是文件浏览器的根目录,默认是执行jupyter notebook命令的那个目录。想要固定某个目录,有几种方式。

最直接的是修改快捷方式或者启动脚本,在命令行指定目录:

jupyter notebook --notebook-dir=/home/username/work

也可以改配置文件:

c.ServerApp.root_dir = '/home/username/work'

Windows用户要注意路径里的反斜杠需要转义,写成双反斜杠或者用正斜杠。我踩过坑,路径填了D:\python_work,结果Python把\p当成特殊字符,直接报错。后来统一用正斜杠,或者路径上再套一层os.path.normpath,干干净净。

3. 网页版登录入口:密码与token机制

3.1 首次登录的token在哪看

Jupyter启动后会自动生成一个token,打印在终端日志里,形如http://localhost:8888/?token=一串字符。很多人第一次启动时找不到这串token,其实就在浏览器地址栏或者终端输出的URL里。如果启动时开了open_browser = False,那就只能去终端日志里找。

在远程服务器上使用时,真正方便的方法是设置固定密码。从Jupyter 5.0之后,不再推荐直接在配置文件里写明文密码,而是用哈希值。设置方法:

from jupyter_server.auth import passwd passwd()

按提示输入两遍密码,会生成一个argon2:开头的哈希字符串,把它填到配置文件中:

c.ServerApp.password = 'argon2:xxxxx'

这个操作的实际意义是:远程访问时不用在URL后面手动拼token,直接输入自己设置的密码即可,方便且安全。token和密码的关系并不是替代,密码设置后token依然生效,但正常的浏览器登录会优先走密码验证。

3.2 局域网与远程的常用映射方式

把Jupyter绑定到局域网是很多人刚接触时的疑惑点。关键参数是--ip=0.0.0.0,然后通过另一台电脑访问http://你的IP:8888。如果你有防火墙,还需要放行相应端口:

# 在Ubuntu上放行8888端口 sudo ufw allow 8888

如果是通过SSH把远端服务器的8888端口映射到本地,那在本地浏览器只需要访问http://localhost:8888即可,本体跟远程服务器之间不需要开任何额外网络端口。

3.3 远程访问的安全底线

把服务器对外开放后,遇到过一件记忆很深刻的事。我在一个云服务器上启动了未加密的Jupyter,忘了设置密码,结果第二天发现后台多了几个莫名其妙的进程,显然是有人在扫描默认端口然后通过Jupyter执行了任意代码。从那次之后养成了三个习惯:

  • 第一,启动前一定要设置密码或者token。
  • 第二,对外访问时使用HTTPS,Jupyter支持自签名证书。
  • 第三,不在服务器上以root身份运行Jupyter服务。

生成自签名证书然后启用HTTPS:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout mykey.key -out mycert.pem

在配置文件中指定:

c.ServerApp.certfile = '/path/to/mycert.pem' c.ServerApp.keyfile = '/path/to/mykey.key'

当然这不是要让大家去搞复杂的安全架构,至少在个人项目层面,把密码设好、别用root跑,这两条守住就能避开绝大多数问题。

4. 目录、单元格与快捷键:操作效率翻倍

4.1 Notebook里的核心交互逻辑

Jupyter单元分两种:代码单元格和Markdown单元格。用Ctrl + Shift + P打开命令面板,几乎能执行所有操作。但在日常使用中,我高度依赖几个快捷键,整理成一张表:

快捷键作用
Esc然后A当前单元格上方插入新单元格
Esc然后B当前单元格下方插入新单元格
Esc然后M切换为Markdown单元格
Esc然后Y切换为代码单元格
Shift + Enter运行当前单元格并移动到下一个
Ctrl + Enter运行当前单元格但不移动
Alt + Enter运行当前单元格并在下方插入新单元格
Esc然后D D删除当前单元格
Esc然后Z恢复删除的单元格
Shift + Tab显示函数或对象的帮助文档

很多人没见过Esc后按D键两次这种删除方式,其实来自Jupyter的vi风格操作。用惯了之后比鼠标右键的删除快得多。

4.2 运行中的状态识别

单元格左侧的In [ ]表示还没执行,In [*]表示正在运行,In [数字]表示已经运行出结果。如果代码陷入死循环,可以点工具栏的停止按钮,或者菜单栏Kernel -> Interrupt。实在卡死到连停止都没反应,只能Kernel -> Restart。但这两个操作之间的区别要理解:Interrupt只是中断当前执行,变量会保留;Restart则清空内核中的所有变量和状态。

我在处理训练模型时通常会先Restart Kernel再重新执行整本notebook,确保不会因为之前的脏状态影响结果。

4.3 添加目录与文档结构

给Notebook添加目录是热词里出现的高频需求。Notebook的目录基于标题层级生成,一个#是一级标题,##是二级标题,Markdown单元格里写完标题后,还需要给单元格起个ID。在Cell -> Cell Toolbar -> Edit Metadata中,为单元格补充id属性,目录插件才能正确锚定。

如果在经典Notebook中,最成熟的是Table of Contents插件,即nbextensions的toc2,安装后每个notebook工具栏会多一个目录按钮。而在JupyterLab里,从3.0开始原生支持左侧目录面板,只要Markdown标题规范,目录自动生成,不需要额外插件。

标题ID的设置在JupyterLab的右侧属性面板直接可以编辑,不需要像旧版本一样手动写JSON。

4.4 自定义快捷键

默认的快捷键不可能覆盖所有人的肌肉记忆,Jupyter是支持自定义的。在Notebook中打开命令面板,选择"Preferences: Open Keyboard Shortcuts"或者直接修改~/.jupyter/nbconfig/notebook.json:

{ "keys": { "command": { "bindings": { "jupyter-notebook:run-cell": { "mac": ["Ctrl+Return"], "linux": ["Ctrl+Enter"] } } } } }

但说实话,日常用到最多的是系统自带组合键,自定义通常解决的是个人习惯差异。比如我就把运行当前单元格从Ctrl + Enter改成Shift + Enter,因为早期写代码时总是想顺手跳下一行。

5. 魔法命令与隐藏技巧:Jupyter不仅是Python解释器

5.1 常用魔法命令清单

Jupyter里的魔法命令以%开头,分为行魔法和单元格魔法,两类在实操中都是高频工具。行魔法只作用于当前这一行,单元格魔法作用于整个单元格,比如%%time会统计整个单元格的执行耗时。

我自己的使用频率排序:

# 测量代码运行时间 %time some_function() # 对整个单元格计时 %%time # 查看变量内存占用 %memit df = pd.read_csv('large.csv') # 列出所有变量 %whos # 直接在前台执行shell命令 !ls -la # 把某个Python文件加载进来执行 %run myscript.py

%%writefile和%load也是经常被低估的两个命令。%%writefile test.py可以直接把一个单元格的内容写成一个.py文件,省去切换编辑器的麻烦。%load myscript.py则是把文件内容加载到当前单元格,适合需要定期更新代码块的场景。

5.2 代码调试与错误处理

Jupyter里的调试向来是痛点的重灾区。最基础的做法是%debug,在发生异常后执行,会进入交互式调试器,可以查看变量的当前状态。

# 在有异常的单元格后运行 %debug

在调试器里可以用p变量名打印变量,u和d切换调用堆栈。数据量大的时候,我更喜欢把怀疑的对象单独写到一个临时单元格里用pd.options.display.max_rows配合抽查,比一步步单步执行更接近工作习惯。

5.3 在Jupyter里打通数据库与大数据

很多人把Jupyter当作单纯的Python脚本工具,实际上它的价值在于交互式探索数据。直接连数据库的操作可以这样:

import pandas as pd from sqlalchemy import create_engine engine = create_engine('postgresql://user:password@host:port/dbname') df = pd.read_sql('SELECT * FROM orders LIMIT 1000', engine)

用Jupyter跑SQL查询,再用pandas处理结果,整个过程都在一个地方完成,这就是notebook相对传统.py文件的核心优势——一边看数据形态一边调整处理逻辑,反馈链路短。

5.4 把Notebook变成报告工具

Notebook不仅能写代码,也能产出相当漂亮的报告。用nbconvert转成HTML或者PDF:

# 转为HTML,隐藏代码只保留结果 jupyter nbconvert --to html --no-input my_report.ipynb # 直接转为幻灯片 jupyter nbconvert --to slides my_presentation.ipynb

如果Team有邮件汇报需求,--to html配合模板还能输出企业风格的报告,用起来非常顺。

6. 目录插件与扩展生态:选对工具省一半心

6.1 nbextensions安装方法

经典Notebook的扩展生态是jupyter_contrib_nbextensions,安装后需要重启Jupyter:

pip install jupyter_contrib_nbextensions jupyter contrib nbextension install --user jupyter nbextensions_configurator enable --user

然后在浏览器页面里会出现Nbextensions标签,打开勾选自己需要的扩展即可。但要注意,不是所有扩展在最新版上都能正常用,尤其是和Notebook 6.x的兼容性有波动。我推荐几个稳定存在的:

扩展名功能作用
Table of Contents (2)自动生成目录,带编号
Autopep8一键美化代码格式
Codefolding代码折叠
ExecuteTime每个单元格运行耗时统计
Snippets自定义代码片段
Hide Input隐藏单元格输入

6.2 JupyterLab扩展的安装与配置

JupyterLab从3.0开始是一个吃扩展的新架构。最值得装的列表:

# 代码格式化 pip install jupyterlab_code_formatter # 目录 pip install jupyterlab-toc # Git版本管理面板 pip install jupyterlab-git # 结构化浏览 pip install jupyterlab-lsp

安装完jupyterlab-lsp后,代码提示和跳转定义的能力会得到明显提升,体验非常接近现代IDE。每次pip安装完都要重启JupyterLab,扩展激活一般没问题。如果遇到扩展不加载,在浏览器F12看console输出,确认插件是否在jupyter labextension list中显示为enabled状态。

6.3 主题与界面美化

默认的Jupyter白底看久了眼睛酸,可以选择暗色主题:

pip install jupyterthemes jt -t onedork -cellw=1200

不过jupyterthemes在Notebook 6+中偶尔会不工作,尤其是混合安装JupyterLab时,它可能会把配置文件写成冲突状态。后来我更推荐用JupyterLab原生主题,Settings -> Theme里直接切换,简单干净。

6.4 插件与版本的依赖关系

Jupyter插件有一个很现实的生态问题:经典Notebook的插件不能直接用在JupyterLab上,JupyterLab的扩展也不是都能回溯兼容。如果你是用Anaconda中的Notebook 6.x,然后遇到某个插件在页面上没有出现,先从版本兼容性去排查,而不是怀疑安装命令写错。

我处理这个问题的方法是:每个项目单独建一个conda环境,用记录的方式锁定版本,这样在旧项目上还能按原样跑,新项目则用最新版本测试。比如:

conda create -n jupyter_env python=3.10 conda activate jupyter_env pip install notebook==6.5.7 jupyterlab==4.0.0

7. 内核管理:多环境多版本共存

7.1 内核是什么,为什么需要管理

Jupyter的内核就是“执行代码的引擎”。默认内核使用的是启动Jupyter的那个Python环境。但是Python环境往往与项目绑定,A项目用TensorFlow 2.x,B项目用PyTorch,如果混在一个环境里,依赖冲突能让人发疯。这时候就需要给Jupyter注册多个内核。

假设现有环境叫myenv:

conda activate myenv pip install ipykernel python -m ipykernel install --user --name myenv --display-name "Python (myenv)"

注册完成后重启Jupyter,新建Notebook时在内核选择栏就可以看到“Python (myenv)”。这个操作的原理是ipykernel把当前Python路径写入一个kernel.json文件,Jupyter根据自己的配置识别人。

7.2 查看与删除内核

# 列出所有已经注册的内核 jupyter kernelspec list # 删除一个内核 jupyter kernelspec remove myenv

如果你发现明明已经删除了conda环境,Jupyter里还是能看到对应的内核,大概率是~/.local/share/jupyter/kernels/里残留了配置,手动删除对应目录即可。

7.3 在Notebook中切换内核的注意事项

切换内核前,最好先保存并重启Kernel,因为notebook文件本身只是JSON,代码的执行状态全部存储在内核中。切换内核会清空当前所有变量,之前跑出来的中间结果如果没保存,就只能重新执行上面所有单元格。Jupyter Notebook/Lab使用技巧大全这个项目如果只让我留一句话,那就是养成“切换环境前先保存输出结果”的习惯。

8. 常见问题与排查技巧实录

8.1 启动即报错的高频问题速查

问题现象原因解决方案
启动后浏览器打开空白页端口被占或者前端资源没加载全强制刷新浏览器缓存;换端口8080-8888
token失效或者输错服务重启后token更新在配置文件中固定密码,不走临时token
内核一直显示启动中Python路径配置错误查看kernel.json,路径改为当前环境的绝对路径
上传大文件一直加载默认文件上传大小限制配置文件设置c.FileContentsManager.max_upload_size_mb = 2048
内网能打开但外网超时云安全组/防火墙策略不透明检查防火墙入站规则,放行对应端口

8.2 Conda和pip混装导致的崩坏

Jupyter本身没问题,因为conda装了一部分包,pip又装了一部分包,两个依赖链冲突就能把环境搞得乌烟瘴气。出现这类情况,别再想着修复,直接新建一个干净环境,按顺序安装:

conda create -n clean_env python=3.10 -y conda activate clean_env pip install jupyterlab notebook # 然后再按项目需要安装其他库

8.3 远程访问时无响应怎么排查

远程环境连不上,第一反应不要是ping,要先在服务器本地跑一次curl http://localhost:8888,确认服务有没有正常监听。如果本地正常而远端访问失败,依次检查防火墙是否放行端口、服务是否绑定了0.0.0.0而不是127.0.0.1、云端控制台的安全组策略。

还有一次远程连不上是因为我在启动命令中设置了--ip=127.0.0.1,本地访问当然正常,但所有外部流量被挡在门外。这种参数级错误,日志里看不出明显报错,最笨也最有效的排查方式是从本地到云端一层层试。

8.4 数据丢失的防范建议

notebook是JSON格式,里面除了代码还有输出,有时候一个文件几百MB,频繁编辑容易出问题。我通常用一个Git仓库保存notebook,同时在重要节点用Ctrl + S持久保存。

从Jupyter 4.0开始,Notebook会自动保存到~/.jupyter/runtime/下的临时文件,重启服务后未关闭的notebook可以尝试用File -> Revert Notebook to Saved恢复。但别指望这个功能有多稳定,真正的保险还是外部版本管理。

9. 工作流周边:自动化与协作

9.1 定时执行Notebook

有人问Jupyter能不能像cron一样定时跑任务,其实可以。把notebook转成Python脚本,然后挂到系统定时任务里:

jupyter nbconvert --to script my_script.ipynb

生成的.py文件保留了单元格的代码,但分割符变成了注释。如果需要完全干净的定时任务,更推荐在notebook中使用papermill:

pip install papermill

然后用命令行指定参数执行:

papermill my_nb.ipynb output.ipynb -p alpha 0.5 -p beta 2.0

这样同一个notebook就能以不同的参数反复运行,适合做批量报表、多组别的模型训练对比。

9.2 和版本管理的结合

在多人共用一个notebook时,Git可以把冲突弄得很痛苦,因为notebook的cell输出部分经常被重复记录,diff非常不友好。推荐安装nbdime:

pip install nbdime nbdime config-git --enable

安装完成后,git diff对于notebook的对比会从JSON层级变成单元格级别的可视化对比,协作体验提升一个档次。

9.3 导出分享与敏感信息处理

导出的HTML如果包含了自己数据库的连接字符串或者密钥,会直接暴露给拿到文件的人。我在分享前会用%%capture捕获不想展示的输出,或者用--no-input参数直接去掉所有代码。改进后的导出命令:

jupyter nbconvert --to html --TemplateExporter.exclude_input=True my_nb.ipynb

也可以直接设置:

jupyter nbconvert --to notebook --clear-output --clear-metadata my_nb.ipynb

这样导出的文件已经完全脱敏,适合分享给同事和团队。

9.4 自定义启动脚本

如果每次启动Jupyter都要敲一串参数、激活环境、钩子插件,写个启动脚本是节省时间的好办法。

#!/usr/bin/env bash source activate work_env jupyter lab --notebook-dir=$HOME/projects \ --ip=0.0.0.0 \ --port=8899 \ --ServerApp.password='argon2:...'

保存后在命令行执行bash start_jupyter.sh即可。如果还需要检测依赖缺失,可以在脚本前面加一行检查,把失败的提示提前暴露出来。

10. 从零到一百:Jupyter用的好,下班早

Jupyter Notebook和JupyterLab本质上是一个交互式开发环境,它的核心价值不在于写代码本身,而在于降低反馈延迟:改一个参数、重新跑到下一行、立刻看到结果。相比传统的脚本循环,省掉大量“回看中间过程”的成本。

个人体会最深的,是JupyterLab 4.x把左侧文件浏览器、多标签窗口、Markdown渲染都整合得很自然,切换多个notebook以及查看同一份数据的不同视角比之前舒服很多。但经典Notebook的价值依然不小,它在插件生态的成熟度和低内存占用上依然有明显优势,两者不必硬选一个,完全可以共存。

如果严格按照我的使用经验来配置一套个人环境,流程是这样的:

  • 安装Anaconda或者Miniconda,建立独立的项目环境
  • 安装ipykernel,注册多个项目内核
  • 设置固定密码、关闭浏览器自动打开
  • 用根目录参数固定默认工作路径
  • 安装nbextensions和JupyterLab扩展,按需开启
  • 用nbdime配合Git管理notebook版本
  • 最后,写一个启动脚本,把所有参数固化到一处

每次换新机器,照这个流程走一遍,半小时内就能恢复到熟悉的开发状态。这套组合拳比什么IDE都更能兼顾“探索式分析”和“工程化落地”的双重需求。

最后分享一个小技巧:在Notebook里点标题旁边的小齿轮,可以直接拖动调整单元格宽度显示比例,配合暗色主题,长时间看代码眼睛会舒服很多。工具是服务人的,别为了追逐新版本而不断折腾环境,把时间留给数据分析本身,比一切都重要。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询