跳转到主要内容

一个用于记录和读取Jupyter和nteract笔记本数据的库

项目描述

scrapbook logo

剪贴簿

Travis Build Status image Documentation Status badge badge Code style: black

剪贴簿库将笔记本的数据值和生成的视觉内容记录为“剪贴”。记录的剪贴可以在未来阅读。

有关如何使用剪贴簿的更多信息,请参阅剪贴簿文档

用例

笔记本用户可能希望在笔记本执行过程中记录生成的数据。这些记录的数据,即剪贴,可以在以后使用或在工作流程中作为输入传递给另一个笔记本。

具体来说,剪贴簿让您

  • 持久化笔记本中的数据可视内容显示为碎片
  • 召回任何持久化的数据碎片
  • 总结笔记本集合

Python版本支持

该库的长期支持目标是Python 3.5+。它目前也支持Python 2.7,直到Python 2在2020年达到生命周期的结束。在此日期之后,Python 2的支持将停止,并且只维护3.x版本。

安装

使用pip安装

pip install scrapbook

对于安装可选IO依赖项,您可以指定单个存储包,如s3azure

pip install scrapbook[s3]

或使用all

pip install scrapbook[all]

模型和术语

Scrapbook定义以下项目

  • 碎片:可序列化的数据值和可视化,如字符串、对象列表、pandas数据框、图表、图像或数据引用。
  • 笔记本:一个包装的nbformat笔记本对象,具有与碎片交互的额外方法。
  • scrapbook:笔记本集合,具有询问集合的接口。
  • 编码器:将数据从/到笔记本存储格式转换的已注册的翻译器。

scrap模型

scrap模型在元组中包含一些关键属性,包括

  • 名称:碎片的名称
  • 数据:由scrapbook api调用捕获的任何数据
  • 编码器:用于将数据编码/解码到/从笔记本的编码器的名称
  • 显示:IPython用于显示可视内容的任何显示数据

API

Scrapbook添加了一些基本的api命令,这些命令可以启用保存和检索数据,包括

  • glue用于持久化带有或不带有显示输出的碎片
  • read_notebook读取一个笔记本
  • scraps提供所有碎片的可搜索字典,按名称排序
  • reglue将另一个笔记本中的碎片复制到当前笔记本
  • read_notebooks从给定路径读取许多笔记本
  • scraps_report显示有关收集的碎片的报告
  • papermill_dataframepapermill_metrics为两个已弃用的papermill功能提供向后兼容性

以下部分提供了有关这些api命令的更多详细信息。

glue用于持久化碎片

在给定的笔记本单元中记录一个scrap(数据或显示值)。

在以后检查输出笔记本时可以检索scrap(记录的值)。

"""glue example for recording data values"""
import scrapbook as sb

sb.glue("hello", "world")
sb.glue("number", 123)
sb.glue("some_list", [1, 3, 5])
sb.glue("some_dict", {"a": 1, "b": 2})
sb.glue("non_json", df, 'arrow')

以后可以使用scrapbook库从输出笔记本中恢复scraps

# read a notebook and get previously recorded scraps
nb = sb.read_notebook('notebook.ipynb')
nb.scraps

scrapbook将根据已注册数据编码器的值类型隐式地表示存储格式。或者,可以通过将encoder参数设置为特定编码器的已注册名称(例如,"json")来覆盖隐式编码格式。

通过生成具有特殊媒体类型以标识内容编码格式和数据的显示输出来持久化这些数据。这些输出在笔记本渲染中并不总是可见,但仍然存在于文档中。然后,Scrapbook可以通过读取这些单元输出在未来重新激活与笔记本关联的数据。

带有显示输出

要显示具有可见显示输出的命名碎片,需要指示该碎片是直接可渲染的。

这可以通过切换display参数来完成。

# record a UI message along with the input string
sb.glue("hello", "Hello World", display=True)

调用将保存Scrap对象的数据和显示属性,使其可见,同时也编码了原始数据。这依赖于IPython.core.formatters.format_display_data函数将数据对象转换为笔记本内核解析的显示和元数据字典。

可以使用另一种模式,指定仅保存显示数据,而不是原始对象。这通过设置编码器为display来实现。

# record an image without the original input object
sb.glue("sharable_png",
  IPython.display.Image(filename="sharable.png"),
  encoder='display'
)

最后,通过传递列表、元组或字典对象作为显示参数,可以控制生成的媒体类型。

sb.glue("media_as_text_only",
  media_obj,
  encoder='display',
  display=('text/plain',) # This passes [text/plain] to format_display_data's include argument
)

sb.glue("media_without_text",
  media_obj,
  encoder='display',
  display={'exclude': 'text/plain'} # forward to format_display_data's kwargs
)

与数据碎片类似,这些可以在以后通过访问碎片的display属性来检索。尽管通常人们会使用笔记本的reglue方法(下面将描述)。

read_notebook读取一个笔记本

读取从指定在path位置的路径加载的笔记本对象。您已经在上述API调用示例中看到了这个函数的使用方法,但本质上这个函数在nbformat的笔记本节点上提供了一个薄包装,并具有提取剪贴本碎片的能力。

nb = sb.read_notebook('notebook.ipynb')

这个笔记本对象遵循nbformat的json模式,允许访问其所需字段。

nb.cells # The cells from the notebook
nb.metadata
nb.nbformat
nb.nbformat_minor

还有一些其他方法提供,其中大部分在下面有更详细的说明。

nb.scraps
nb.reglue

这个抽象还使保存的内容以DataFrame的形式可用,每个键和源都进行了引用。在以后的版本中还将提供更多这些方法。

# Produces a data frame with ["name", "data", "encoder", "display", "filename"] as columns
nb.scrap_dataframe # Warning: This might be a large object if data or display is large

笔记本对象还有一些为了与papermill的笔记本对象模型向后兼容而保留的旧函数。因此,它可以用来读取papermill执行统计以及剪贴本抽象。

nb.cell_timing # List of cell execution timings in cell order
nb.execution_counts # List of cell execution counts in cell order
nb.papermill_metrics # Dataframe of cell execution counts and times
nb.papermill_record_dataframe # Dataframe of notebook records (scraps with only data)
nb.parameter_dataframe # Dataframe of notebook parameters
nb.papermill_dataframe # Dataframe of notebook parameters and cell scraps

笔记本读取器依赖于papermill的已注册iorw以启用对各种来源的访问,例如但不限于S3、Azure和Google Cloud。

scraps提供了一个名称到碎片的查找。

scraps方法允许访问特定笔记本中的所有碎片。

nb = sb.read_notebook('notebook.ipynb')
nb.scraps # Prints a dict of all scraps by name

此对象还有一些其他方法,方便转换和执行。

nb.scraps.data_scraps # Filters to only scraps with `data` associated
nb.scraps.data_dict # Maps `data_scraps` to a `name` -> `data` dict
nb.scraps.display_scraps # Filters to only scraps with `display` associated
nb.scraps.display_dict # Maps `display_scraps` to a `name` -> `display` dict
nb.scraps.dataframe # Generates a dataframe with ["name", "data", "encoder", "display"] as columns

这些方法允许简单用例而无需挖掘模型抽象。

reglue将碎片复制到当前笔记本中。

使用reglue,可以将任何粘附在一个笔记本中的碎片粘附到当前笔记本中。

nb = sb.read_notebook('notebook.ipynb')
nb.reglue("table_scrap") # This copies both data and displays

任何数据和显示信息都将直接复制到当前正在执行的笔记本中,就像用户再次在原始源上调用glue一样。

还可以在此过程中重命名碎片。

nb.reglue("table_scrap", "old_table_scrap")

最后,如果希望尝试不检查存在性而reglue,可以将raise_on_missing设置为在失败时仅显示消息。

nb.reglue("maybe_missing", raise_on_missing=False)
# => "No scrap found with name 'maybe_missing' in this notebook"

read_notebooks读取多个笔记本。

将位于给定path的所有笔记本读取到剪贴本对象中。

# create a scrapbook named `book`
book = sb.read_notebooks('path/to/notebook/collection/')
# get the underlying notebooks as a list
book.notebooks # Or `book.values`

该路径重用papermill的已注册iorw来列出和读取来自各种来源的文件,这样非本地url可以加载数据。

# create a scrapbook named `book`
book = sb.read_notebooks('s3://bucket/key/prefix/to/notebook/collection/')

可以使用剪贴本(在此示例中为book)来回忆笔记本集合中的所有碎片。

book.notebook_scraps # Dict of shape `notebook` -> (`name` -> `scrap`)
book.scraps # merged dict of shape `name` -> `scrap`

scraps_report显示有关收集的碎片的报告

可以使用剪贴本集合来生成一个关于集合中所有碎片的scraps_report,作为Markdown结构化输出。

book.scraps_report()

此显示可以基于碎片和笔记本名称进行筛选,以及启用或禁用显示的整体标题。

book.scraps_report(
  scrap_names=["scrap1", "scrap2"],
  notebook_names=["result1"], # matches `/notebook/collections/result1.ipynb` pathed notebooks
  header=False
)

默认情况下,报告将仅填充视觉元素。要报告数据元素,请设置include_data。

book.scraps_report(include_data=True)

papermill支持

最后,剪贴本提供了两个向后兼容的特性,用于废弃的papermill功能。

book.papermill_dataframe
book.papermill_metrics

编码器

编码器可以通过键名访问注册在encoders.registry对象上的编码器对象。要注册新的数据编码器,只需调用

from encoder import registry as encoder_registry
# add encoder to the registry
encoder_registry.register("custom_encoder_name", MyCustomEncoder())

编码类必须实现两个方法,encodedecode

class MyCustomEncoder(object):
    def encode(self, scrap):
        # scrap.data is any type, usually specific to the encoder name
        pass  # Return a `Scrap` with `data` type one of [None, list, dict, *six.integer_types, *six.string_types]

    def decode(self, scrap):
        # scrap.data is one of [None, list, dict, *six.integer_types, *six.string_types]
        pass  # Return a `Scrap` with `data` type as any type, usually specific to the encoder name

这可以将碎片读取并转换成表示其内容或位置的json对象,并将这些字符串重新加载到原始数据对象中。

文本

一种基本的字符串存储格式,将数据以Python字符串的形式保存。

sb.glue("hello", "world", "text")

json

sb.glue("foo_json", {"foo": "bar", "baz": 1}, "json")

pandas

sb.glue("pandas_df",pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]}), "pandas")

papermill已弃用的record功能

scrapbook提供强大且灵活的记录模式。这个库取代了papermill现有的record功能。

papermill record的文档存在于ReadTheDocs上。简而言之,已弃用的record函数

pm.record(name, value):允许将值保存到笔记本中[API文档]

pm.record("hello", "world")
pm.record("number", 123)
pm.record("some_list", [1, 3, 5])
pm.record("some_dict", {"a": 1, "b": 2})

pm.read_notebook(notebook):可以使用pandas读取输出笔记本到dataframe中,以恢复记录的值。例如

nb = pm.read_notebook('notebook.ipynb')
nb.dataframe

Papermill record弃用的理由

Papermill的record函数因以下限制和挑战而被弃用

  • record函数没有遵循papermill笔记本线性执行的模式。将record描述为papermill的附加功能显得有些尴尬,实际上感觉就像是在描述一个第二级不太发达的库。
  • 记录/读取需要将所有数据转换为JSON格式。这对于dataframe来说是一个繁琐且痛苦的过程。
  • 将记录的值读入dataframe会导致dataframe形状不直观。
  • 比其他papermill组件(其中可以注册自定义操作符)的模块化和灵活性更少。

为了克服Papermill中的这些限制,决定创建Scrapbook

项目详情


下载文件

下载适合您平台版本的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

scrapbook-0.5.0.tar.gz (134.8 kB 查看哈希)

上传时间

构建分发

scrapbook-0.5.0-py3-none-any.whl (34.7 kB 查看哈希)

上传时间 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页面