14

我的 Jupyter 笔记本越来越长,这使得导航变得困难。

我想将每一章(以标题 1 开头的 Cel)保存到不同的文件中。我怎样才能做到这一点?在笔记本之间剪切和粘贴多个单元格似乎是不可能的。

4

3 回答 3

11

这是我使用的方法 - 它有点尴尬,但它有效:

  1. 使用菜单中的 File->Make Copy 制作主笔记本的多个副本。为要提取的每一章制作一份副本。
  2. 重命名每章的副本:例如将“master-copy0”重命名为“Chapter 1”。
  3. 删除不属于第 1 章的每个单元格 - 例如在命令模式下使用“dd”。
  4. 保存缩写文件。
  5. 对每一章重复步骤 3 和 4。

我相信开发人员可能正在为未来的版本开发更好的解决方案。

于 2014-09-21T17:00:19.587 回答
2

笔记本文件是 json 格式,所以我将所有数据都以 JSON 格式获取并自动将其拆分为多个文件。

这段代码是我做的。

代码似乎很复杂,但如果你检查一下它就很简单,这是一个单独文件的示例,http: //www.fun-coding.org/DS&AL4-1.html 我也对其进行了转换拆分后作为HTML。

import json
from pprint import pprint
import re

def notebook_spliter(FILENAME, chapter_num):

    with open(FILENAME + '.ipynb') as data_file:    
        data = json.load(data_file)

    copy_cell, chapter_in = list(), False

    regx = re.compile("## [0-9]+\. ")
    for num in range(len(data['cells'])):
        if chapter_in and data['cells'][num]['cell_type'] != 'markdown':
            copy_cell.append(data['cells'][num])
        elif data['cells'][num]['cell_type'] == 'markdown':
            regx_result = regx.match(data['cells'][num]['source'][0])

            if regx_result:
                print (regx_result.group())
                regx2 = re.compile("[0-9]+")
                regx2_result = regx2.search(regx_result.group())
                if regx2_result:
                    print (int(regx2_result.group()))
                    if chapter_in == False:
                        if chapter_num == int(regx2_result.group()):
                            chapter_in = True
                            copy_cell.append(data['cells'][num])
                    else:
                        if chapter_num != int(regx2_result.group()):
                            break
            elif chapter_in:
                copy_cell.append(data['cells'][num])

    copy_data["cells"] = copy_cell
    copy_data["metadata"] = data["metadata"]
    copy_data["nbformat"] = data["nbformat"]
    copy_data["nbformat_minor"] = data["nbformat_minor"]
    with open(FILENAME + '-' + str(chapter_num) + '.ipynb', 'w') as fd:
        json.dump(copy_data, fd, ensure_ascii=False)

这是一个检查笔记本文件中章节编号的功能。我在markdown单元格中使用'## 1. chapter name'将章节号添加到笔记本文件中,所以只需检查##数字。带有正则表达式的模式。

然后,接下来的代码是将单元格的数据复制到这一章编号中,并将仅复制的单元格和其他(元数据、nbformat 和 nbformat_minor)保存到单独的文件中。

copy_data = dict()
FILENAME = 'DS&AL1' 
CHAPTERS = list()
with open(FILENAME + '.ipynb') as data_file:    
    data = json.load(data_file)

for num in range(len(data['cells'])):
    if data['cells'][num]['cell_type'] == 'markdown':
        regx_result = regx.match(data['cells'][num]['source'][0])

        if regx_result:
            regx2 = re.compile("[0-9]+")
            regx2_result = regx2.search(regx_result.group())
            if regx2_result:
                CHAPTERS.append(int(regx2_result.group()))
print (CHAPTERS)

for chapternum in CHAPTERS:
    notebook_spliter(FILENAME, chapternum)
于 2018-05-18T11:39:56.733 回答
1

最简单的方法可能是在文本编辑器中编辑 .ipnb 文件。下面我列出了一个非常简单的笔记本的内容。

笔记本看起来像

第1章

[1]中:1+1

输出[1]:2

第2章

[2]中:2+2

输出[2]:4

要取出第 1 章并将其放在第 2 章后面,您可以这样做

  1. 搜索“级别”:1
  2. 你会发现 { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Chapter 1" ] } 和 { "cell_type": "heading", "level": 1,“元数据”:{},“来源”:[“第2章”]},
  3. 将所有内容从第一个搜索结果的开头移动到第二个搜索结果结尾的下方
  4. 注意逗号

您可以以类似的方式操作多个笔记本。

这是示例的 .ipnb 文件

{
 "metadata": {
  "name": "",
  "signature": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Chapter 1"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "1+1"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 1,
       "text": [
        "2"
       ]
      }
     ],
     "prompt_number": 1
    },
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Chapter 2"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "2+2"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 2,
       "text": [
        "4"
       ]
      }
     ],
     "prompt_number": 2
    }
   ],
   "metadata": {}
  }
 ]
}
于 2014-10-01T02:28:57.950 回答