zzhanglii
2023/02/13阅读:50主题:山吹
一文带你了解Notebook前世今生和未来
引言
近年来,用于数据科学的Notebook越来越受欢迎,有越来越多的人认为Notebook是交流数据科学过程和分享数据结论的最佳平台。
这个增长趋势我们从Github上也可以得到印证:Jupyter(早期被称作IPython) Notebook托管在Github上的数量,已经从2015年的20万个攀升到如今的1000+万个!根据收集到的数据显示,托管在GitHub上的Jupyter Notebook数量几乎呈指数级增长:

这个趋势引出了一个问题:是什么推动Notebook作为数据科学工作的首选环境而得到越来越广泛的使用?—— Why Notebook?
接下来小编带领大家一起来了解Notebook的前世今生以及将来的发展趋势,文章有点长,但读完一定收货满满哦。
Notebook的前世
起源于实验室
Notebook最早是从实验室的笔记本(手写的笔记本)中汲取的灵感。在学术研究中,实验方法、实验结果和见解按顺序记录在实验室笔记本中。这种风格的文档非常适合学术研究,能够保证实验是“可理解的”、”可重复的”,并且容易检索。
随着实验研究过渡到计算环境,实验室笔记本迎来了虚拟化、电子化转型。第一个Notebook计算是大约30年前在Mathematica中引入的。自Mathematica以来,我们见证了Notebook产品的激增,最被大众所熟知的:Jupyter,MATLAB,R Markdown和Apache Zeppelin。
然而,Notebook与其他编程环境的区别究竟是什么?是什么让它比Shell、文本编辑器或IDE(集成开发环境) 更好?虽然各式各样的Notebook产品在界面和语言上存在诸多差异,但它们基本都遵循共同的设计模式:
-
独立执行和显示代码块输出的能力。 -
代码与自然语言交织在一起的能力。

那么,为什么这种设计模式推动了Notebook在数据科学中广泛使用呢?
科学方法的扩展
作为一种科学实践,数据科学从科学方法(scientific method)中汲取了大部分研究方法和流程。Cathy O'Neill在她的《Doing Data Science》一书中说,数据科学过程实际上只是科学方法的延伸:
-
列出问题 -
做背景研究 -
构建假设 -
通过实验来检验你的假设 -
分析数据并得出结论 -
分享和交流结果
与科学方法类似,数据科学在很大程度上是一个探索和迭代的过程:你可以将问题解构为多个独立探索的逻辑块,并一步步迭代构建出更加细致的结论。这种方法使得数据科学代码模块化和可重复性显得尤为重要。
Notebook使得原本整体式的脚本分解为可执行代码的模块化集合。用户能够独立于Notebook的其它部分运行代码块并检查其各自的输出。这个功能对于日益复杂的数据科学工作流中管理认知和复杂计算方面至关重要。
在研究科学方法与Cathy O'Neill提出的数据科学过程之间差异时,我们发现人们越来越注重最后一步:分享和交流结果。来自datascience.com的William Merchan在JupyterCon 2017大会主题演讲中引用了Forrester的一项调查,该调查指出,有99%的受访公司认为数据科学是一项非常重要的发展技能,但这些公司中只有22%的公司看到了数据科学切实的商业价值。
他同时提到,发现数据科学的潜力和实现其价值之间的脱节源于这样一个事实:很难通过编排将数据科学所做的工作进行交流和传递洞察力。随着数据科学持续成为每个行业中越来越重要的部分,数据科学的研究者和从业者数量也在不断增加。然而随着数量的增加,这些数据科学从业者的素养差距也日渐扩大。对如今的数据团队来说,有效地交付和传达来自数据科学工作的真实见解变得越来越具有挑战性。

文学化编程
1983年,Donald Knuth提出了一种新的编程范式,称为“文学化编程”。
高德纳(Donald Knuth)是算法和程序设计技术的先驱者,计算机排版系统TeX和字型设计系统Metafont 的发明者,他因这些成就和大量创造性的影响深远的著作而誉满全球。
他是《计算机程序设计的艺术》(The Art of Computer Programming)的作者,本书堪称计算机科学理论与技术的经典巨著,有评论认为其作用与地位可与数学史上欧几里得的《几何原本》相比。高德纳因而荣获1974年度的图灵奖。
高德纳同时也是排版软件TeX和字型设计系统METAFONT发明人,所著描述基本算法与数据结构的巨作《计算机程序设计的艺术》被《美国科学家》杂志列为20世纪最重要的12本物理科学类专著之一,与爱因斯坦《相对论》、狄拉克《量子力学》、理查·费曼《量子电动力学》等经典比肩而立。
Notebook通过利用“文学化编程”的编程风格来解决数据科学中存在的挑战。“文学化编程”是这样一种范式,它将模块化的代码块与代码上下文的自然语言解释块交织在一起。Donald Knuth在描述他开发WEB编程语言和文档系统的经验时阐述了这个概念:
“当我第一次有这个想法并最终开发成为系统,我认为我将设计一种”自上而下“的编程语言,先给出最上层的描述并持续进行完善。另一方面,我经常以“自下而上”的方式创建程序的主要部分,从基本过程和数据结构的定义开始,逐渐构建越来越强大的子例程。自上而下和自下而上是相反的方法:一种更适合程序阐述,另一种更适合程序创建。但是在获得了一些经验之后,我开始意识到没有必要必须在自上而下和自下而上之间做出选择,因为最好将程序视为网状的而不是树状。程序的层次结构重要,但更重要的其实是其结构关系。再复杂的软件也是由简单的部分和这些部分之间的简单关系组成。而程序员的任务则是陈述这些部分和关系,以最适合人类理解的顺序去编排 - 而不是按照一些严格确定的顺序,比如自上而下或自下而上。
传统的结构化编程使人们花费大量的力气让我们的代码顺应计算机的逻辑顺序,指导计算机做事,而文学化编程则是让我们集中精力向人类解释我们需要计算机做什么,因此更顺应我们的思维逻辑。
由此产生的Notebook编程环境,便是针对人类理解进行了优化,也是Notebook在数据科学时代蓬勃发展的原因。它使数据团队能够非常方便的阐述和交付他们的工作,以便受众可以轻松的理解。在数据科学的输出日益成为关键决策的输入环境下,这种能有效提升洞察力的方式变得至关重要。
数据团队面临的挑战,除了核心科学和分析能力外,他们还需要成为讲故事的专家。围绕他们的作品认真构建叙事,既吸引读者的阅读兴趣又传递了有效的信息。Notebook提供的独特环境使得数据团队能够按照他们的思维过程顺序,而不是计算机规定的顺序来构建他们的分析和叙述,文学化编程让他们能够讲述更多有趣、有料和引人入胜的数据故事。
Notebook的解释和特点
Notebook是文学化编程的具体实践,它是一种基于网页的交互式计算方式,用户可在Notebook中进行开发、文档编写、运行代码、展示结果以及结果分享。与传统非交互式开发环境相比,Notebook最大的特点是允许逐单元格(cell)执行脚本。
代码块是Notebook最基本的单元,包括输入(代码)、输出,同时也包括自然语言。这样由代码块、自然语言交织组成的一个逻辑体就是一个Notebook,它特别适合数据分析或数据探索。
我们通过一系列的探索过程最终生成一些结论就生成了一个Notebook,也可以称之为一个模型,例如分析模型或者是机器学习模型,当然也可称之为一个数据故事。
-
Notebook可以很好的展示数据处理、数据分析、数据科学的过程,是很好组织形式。 -
Notebook可以方便的分享,如果给老板或业务人员展示代码或SQL,他们会很难理解,而通过Notebook输出结果的可视化展示可以让受众很容易理解,并且代码不需要实际再执行一遍。
Notebook是数据科学领域至关重要的工具,数据科学家使用Notebook进行实验和探索任务。近年来随着大数据的发展,业务分析师等非技术人员也越来越多地开始使用Notebook。
Jupyter和Jupyter Notebook
Jupyter下的三个前端系统/产品
-
Jupyter Notebook:经典的Notebook界面。用于创建和共享计算文档的原始web应用程序,它提供了简单、精简、以文档为中心的体验。 -
JupyterLab:下一代Notebook界面。用于笔记本、代码和数据的最新基于web的交互式开发环境,其灵活的界面允许用户配置和编排数据科学、科学计算、高频计算和机器学习的工作流。模块化设计可方便的扩展插件和丰富功能。 -
JupyterHub:将Notebook的强大功能带给用户组。它让用户能够访问计算环境和资源,而不会给用户带来安装和维护任务的负担。用户(包括学生、研究人员和数据科学家)可以在自己的工作空间中使用共享资源完成工作,系统管理员可以有效地管理共享资源。

Jupyter Notebook
许多用Python的数据科学家都会选择使用的工具:Jupyter Notebook
"The Jupyter Notebook was designed for literate programming — mixing code, text, results, figures, and explanations together into one seamless document."
“Jupyter Notebook专为文学化编程而设计 — 它将代码、文本、结果、图表及详细阐释融合在一起,形成一份优美流畅的文档。”

Jupyter是Notebook类产品的鼻祖,它是Notebook的典型代表,也是目前很多数据科学家用来做数据实验、人工智能开发的系统和平台,后面的Notebook类产品的架构基本都是由Jupyter演变和进化来的。

历史
Jupyter Notebook是从一个名为IPython的项目演变而来的。
IPython早在2007年就开始作为Python的REPL(read-eval-print loop)工具。2011年,它通过Qt框架获得了专用的前端,同年晚些时候,它还获得了基于Web的前端,称为IPython Notebook。
随着时间的推移,IPython Notebook支持的语言不断增多,因此于2014年创建了Jupyter项目,并在2015年项目独立出来。Jupyter是Julia、Python和R的结合体,这是用于数据分析的三种最流行语言。
Jupyter Notebook是重新命名的IPython Notebook。它不局限于Python内核,而是通用的,也可以与其他内核交互,如Julia和R。
IPython基本变成了Jupyter的Python内核,但也有很多来自于IPython但独立于语言之外的功能集成到了Jupyter core,比如Notebook格式(nbformat),我们从文件的扩展名.ipynb中仍可以看出。
架构
下图展示了单用户Jupyter Notebook的高级构建模块。浏览器使用WebSockets与HTTP服务器通信。该服务器使用Tornado(用Python实现的流行HTTP服务器)。
另一方面,服务器将消息中继到内核进程,进程间通信通过ZeroMQ完成,这是一种简化实现常见通信模式(如客户端/服务器和发布/订阅)的抽象。服务器和内核位于同一位置(即在同一主机中运行)。
当我们运行Jupyter Notebook时,服务器和内核在本地机器上运行,但其实也可以在远程主机上运行。

多用户
Jupyter Notebook支持了将多个客户端连接到单个内核。
数据模型
Notebook的内容以JSON格式存储在带有扩展名的文本文件中,并且将计算结果也内联存储在此文件中。这样当你与其他人共享Notebook文件时,即使他们无法自己运行代码,也可以看到整个分析过程以及输出的结果。
通信
正如我们上面提到的,Web服务器使用ZeroMQ与内核进程进行通信。
下面是一些连接通道类型,也称为通道或套接字。
-
shell:用于接收来自所有客户端的输入 -
io_pub:用于向所有客户端广播消息 -
stdin:客户端用于从输出发送数据,例如当代码的执行提示用户输入信息时(例如Python 的input()) -
control:与shell相同,但由于优先级较高而分开,例如显示关机和调试消息(如果shell进程卡住很有用) -
heartbeat:客户端用于定期发送ping检测信号,以确定服务器是否仍处于活动状态/连接状态
客户端(浏览器)使用WebSockets与Web服务器通信,但它也会定期Ajax请求一些特殊消息。
WebSocket是粘性的:所有消息都从单个连接交换,该连接持续到内核重新启动或页面重新加载(长连接)。
消息流
我们考虑以下几个场景,并检查正在交换哪些消息。要查看发送到服务器的请求,我们可以使用Chrome的网络选项卡并检查WS(WebSocket)选项卡。将有一个条目用于Web套接字连接和通过此连接发送的消息。

执行代码
用户运行一段代码。假设它们已经连接到Python内核:
import time
i = 0
while i < 5:
print(i)
i += 1
time.sleep(5)
这时候的交互消息顺序如下(消息类型/通道名称):
-
→ execute_request / shell -
← status / iopub (status=busy) -
← execute_input / iopub -
← stream / iopub (multiple of them) -
← status / iopub (status=idle) -
← execute_reply / shell
代码在①中作为有效载体发出,然后服务器回复以指示它正忙于处理②中的请求。它还将代码③广播给所有客户端(包括请求者),并且在生成stdout/stderr时,它会在④中多次流式传输该代码。
当计算完成后,TNE(Trusted Network Environment )服务器将自身标记为空闲⑤,然后通过⑥指示执行结束。这个序列非常接近 Web 服务器和内核之间的序列。
等待客户输入
当用户运行一段阻止请求某些用户信息的代码:
r = input('enter a number:')
print(r)
交互的消息顺序如下(消息类型/通道名称):
-
→ execute_request / shell -
← status / iopub (status=busy) -
← execute_input / iopub -
← input_request / stdin
与执行代码流中出现相同的消息序列,但现在内核将向客户端发送消息input_request ④并进入阻止等待input_reply
用户键入值后,消息将遵循继续执行。
-
→ input_reply / stdin -
← stream / iopub -
← status / iopub (status=idle) -
← execute_reply / shell
但需注意的是,多个单元共享同一个单线程内核进程。在上面的例子中,如果内核在等待input_reply时被阻塞,它将不会处理来自其他单元的代码。
这可以通过添加第二个单元格来测试:
print('hello')
然后执行第一个单元格,但在提供输入之前执行第二个单元格。在第一个单元格中提供值之前,"hello"不会显示,如下图展示。

图表展示
用户运行一段返回丰富数据的代码,即交互式绘图:
import plotly.express as px
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
fig.show()
-
→ execute_request / shell -
← status / iopub (status=busy) -
← execute_input / iopub -
← display_data / iopub -
← status / iopub (status=idle) -
← execute_reply / shell
这与基本的执行流非常相似,只是输出是通过消息display_data ④发送的。此消息的内容是一个mime类型对应的JSON对象,对于plotly是application/vnd.plotly.v1+json。
中断执行
当用户运行代码卡住,通过Cmd+C或点击停止按钮可中断执行。
while True:
pass
交互的消息顺序如下(消息类型/通道名称):
-
→ execute_request / shell -
← status / iopub (status=busy) -
← execute_input / iopub
按下Cmd+C:
-
→ kernel_info_request / shell -
← error / iopub (ename=KeyboardInterrupt) -
← execute_reply / shell -
← status / iopub (status=idle) -
← kernel_info_reply / shell
注:关于中断的交互形式取决于内核所支持的中断类型,中断类型包括消息中断和信号中断,上面这个例子属于消息中断。另:有些内核是不支持消息中断的,必须通过调用Server的API向Kernel的进程发送中断信号。
小结
自此我们了解到IPython如何演变成Jupyter Notebook并成为其Python内核。然后,我们查看了它的体系架构,尤其是围绕消息传递的体系结构,并且对不同的代码场景对消息队列进行了实际分析。总体而言,这是一个相对简单的架构,但它巧妙地使用多个通道来处理不同的用例。
Notebook的今生
各式各样的Notebook
早期的Notebook主要用于学术领域,随着近十年来Notebook逐渐由学术界进入到产业领域,越来越多的Notebook涌现在市场中,如开源的Jupyter、Apache Zeppelin,商业化托管的Google Colab、JetBrains Datalore、Deepnote等,支持混合多语言的Polynote等。
尽管Notebook的种类众多,其最核心的构成均包含三大组件:
一是前端的客户端,由有序的输入/输出单元格列表构成,用户可以在这些单元格中输入代码、文本等。
二是Notebook的Server,Server负责Notebook文件的保存,Kernel会话的管理及交互消息的管理。
三是后端内核(Kernel),其可配置在本地或云端,Kernel负责整个代码的执行。
代码由前端传递给Kernel,Kernel运行代码后将结果返还给用户。Kernel决定了Notebook的计算性能。
我们以Jetbrains Datalore为例,大致了解一下目前Notebook发行版具备的常见功能
特征共性
-
兼容Jupyter Notebook -
支持的编程语言:Python, R等 -
支持的数据源类型: -
Jupyter libraries (例如SQLAlchemy, psycopg2) -
传统数据库 (例如MySQL, PostgreSQL) -
数据仓库 (例如Snowflake)
-
-
支持文件存储 -
支持的数据可视化类型: -
Jupyter data visualization (例如Matplotlib, Altair, Plotly) -
UI for building charts
-
-
全面、实时的反应 -
支持Notebook执行计划
管理特性
-
默认情况下,环境可以重现 -
内置版本历史记录 -
支持多人协作编辑 -
支持同时使用多个编辑器 -
支持批注和评论 -
支持树状查看笔记本
下方的表格展示了各式各样Notebook产品的功能对比(来源:https://datasciencenotebook.org)

Jupyter Lab
Jupyter Lab是基于Jupyter Notebook、Jupyter架构的下一代Notebook的实现。
JupyterLab is a next-generation web-based user interface for Project Jupyter
它用于交互式和可重现计算的可扩展环境。相对于Jupyter Classic Notebook最大的变换是实现了前后端分离(Classic Notebook UI不具备扩展性),设计了全新的、开放的、可扩展的前端架构。
Jupyter Lab为浏览器中的交互式计算和数据科学提供了一个通用框架。
JupyterLab is a flexible, extensible interface for interactive computing.
它使用Python,Julia,R和其他语言。除了为现有Notebook提供改进的界面外,Jupyter Lab还在同一界面中引入了文件浏览器、控制台、终端、文本编辑器、Markdown 编辑器、CSV 编辑器、JSON 编辑器、交互式地图、交互小组件等。该体系结构是完全可扩展的,对开发人员开放进行扩展。
Jupyter Lab核心作为交互计算和数据科学的前端通用框架的主要特点:
-
现代JavaScript开发:基于npm的打包、Typescript、phosphor.js -
清晰的模型/视图分离 -
以灵活和集成的方式使用模块组件 -
分离良好的公共/私有API -
支持第三方完全扩展
Jupyter Lab模块组成如下图:

其他Notebook发行版产品
我们这里列举了Deepnote、Datalore、Hex以及SmartNoteBook的产品Slogan以及特色功能:
Deepnote
-
slogan:Data Science notebook for teams -
feature -
Python + SQL -
real-time collaboration -
command palette -
workspace permissions worksapce -
export PDF -
import notebook from github/google drive -
SSH Key
-
Datalore
-
slogan: Collaborative data science platform -
feature -
Python SQL R Kotlin Scala -
No-Code Automations -
smart coding assistance -
interactive BI apps -
data integrations -
scalable infrastructures -
dataframe statistics -
csv file previews and editing
-
Hex
-
slogan: A magical, modern platform for data science and analytics -
feature -
Python SQL R Markdown Text -
No-Code -
shuntings visualizations -
多种云数仓 -
graphs -
real-time collaboration
-
SmartNoteBook
-
slogan:为数据分析/科学而生 -
feature -
Python R Julia Sagemath SQL Markdown Text -
实时协作 -
多种数据源, 数据集成 -
密保 -
调度 -
一键分享 -
支持创建服务API -
no-code插件,可视化插件 -
workspace permissions -
GitLab/Github
-
四个产品的共通点
Deepnote、Datalore、Hex、SmartNotebook代表了数据科学、Notebook发展趋势:智能化、云原生、平民化、工程化。
-
开箱即用:兼容Jupyter Notebook,集成主流数据基础设施、主流数据分析、机器学习框架;降低安装、配置和维护成本。 -
云化:云原生的架构;支持主流的云环境、云数据仓库;SaaS 化的服务模式。 -
协作:数据/模型的协同开发/建模,探索、开发和运行维护流程间的协同,通过Notebook 构建模型交流的社区和数据智能应用的生态。 -
低代码:通过扩展低代码(可视化、数据转换、机器学习、交互组件)的插件,降低数据科学的门槛。 -
工程化:扩展了Notebook的数据集成、调度、可视化仪表盘、模型服务(FaaS)、模型市场等功能,覆盖数据科学全流程(数据集成、数据分析及探索、数据服务、模型服务及应用),不仅是数据科学探索平台,也是数据及模型的生产平台。
Notebook的未来...
数据科学越来越重要,是数据智能化应用、组织转型创新的关键,Notebook是目前数据科学、人工智能最为重要的承载方式,发行版(产品化)的Notebook涵盖组织的数据供应链的全流程,不仅可以作为试验探索平台,也可以作为数据、模型的生产应用平台。Notebook生态会越来越庞大,开发者或使用者会快速增长,Notebook越来越平民化,数据科学的门槛会越来越低。
最后
祝编程快乐,兔年大吉!

作者介绍