【问题标题】:Configure a first cell by default in Jupyter notebooks在 Jupyter 笔记本中默认配置第一个单元格
【发布时间】:2016-03-24 07:09:10
【问题描述】:

有没有办法为 Jupyter 笔记本中的特定 python 内核配置默认的第一个单元?我同意默认的 python 导入不符合良好的编码习惯。

那么,我可以配置笔记本,使新 python 笔记本的第一个单元始终是

import numpy as np

例如?

【问题讨论】:

  • 抱歉,自动更正更改了 Jupiter 标题中的 jupyter :S
  • 你有没有想出办法做到这一点?这将非常有用,因为我在新笔记本中做的第一件事就是一堆标准导入!
  • 看起来 jupyter 开发人员不想这样做,但建议编写一个笔记本扩展。希望知道如何做到这一点的人会这样做! github.com/jupyter/notebook/issues/640

标签: python jupyter jupyter-notebook


【解决方案1】:

如上所述创建 IPython 配置文件是一个很好的第一个解决方案,但在 IMO 中它并不完全令人满意,尤其是在代码共享方面。

通过命令 exec_lines 导入的库的名称不会出现在笔记本中,因此您很容易忘记它。在另一个配置文件/机器上运行代码会引发错误。

因此我建议使用 Jupyter 笔记本扩展,因为会显示导入的库。 它避免了在笔记本开头总是导入相同的库。 首先你需要安装 Jupyter 的 nbextension。 您可以克隆回购:https://github.com/ipython-contrib/jupyter_contrib_nbextensions 或使用点子:pip install jupyter_contrib_nbextensions

然后,您可以通过将文件夹“default_cells”添加到安装 nb 扩展的路径来创建 nb 扩展。例如在 Ubuntu 上是 /usr/local/share/jupyter/nbextensions/.,可能在 windows 上:C:\Users\xxx.xxx\AppData\Roaming\jupyter\nbextensions\

您必须在此文件夹中创建 3 个文件:

  • main.js 包含扩展的js代码
  • Jupyter 中 API 的 default_cells.yaml 描述
  • README.MD 出现在 API 中的读者常用描述。

我使用的代码来自:https://github.com/jupyter/notebook/issues/1451mymain.js 是:

    define([
        'base/js/namespace'
    ], function(
        Jupyter
    ) {
        function load_ipython_extension() {
          if (Jupyter.notebook.get_cells().length===1){
       //do your thing
            Jupyter.notebook.insert_cell_above('code', 0).set_text("# Scientific libraries\nimport numpy as np\nimport scipy\n\n# import Pandas\n\nimport pandas as pd\n\n# Graphic libraries\n\nimport matplotlib as plt\n%matplotlib inline\nimport seaborn as sns\nfrom plotly.offline import init_notebook_mode, iplot, download_plotlyjs\ninit_notebook_mode()\nimport plotly.graph_objs as go\n\n# Extra options \n\npd.options.display.max_rows = 10\npd.set_option('max_columns', 50)\nsns.set(style='ticks', context='talk')\n\n# Creating alias for magic commands\n%alias_magic t time");
          }
        }
        return {
            load_ipython_extension: load_ipython_extension
        };
    });

.yaml 必须像这样格式化:

    Type: IPython Notebook Extension
    Compatibility: 3.x, 4.x
    Name: Default cells
    Main: main.js
    Link: README.md
    Description: |
      Add a default cell for each new notebook. Useful when you import always the same libraries$
    
    
    Parameters:
    - none

和 README.md

    default_cells
    =========
    
    Add default cells to each new notebook. You have to modify this line in the main.js file to change your default cell. For example
    
    `Jupyter.notebook.insert_cell_above('code', 0).set_text("import numpy as np/nimportpandas as pd")`
    
    
    You can also add another default cell by creating a new line just below :
    
    `Jupyter.notebook.insert_cell_above('code', 1).set_text("from sklearn.meatrics import mean_squared_error")`
    
    **Don't forget to increment 1 if you want more than one extra cell. **

然后您只需在 Jupyter 中出现的新标签“nbextensions”中启用“默认单元格”扩展。

唯一的问题是它通过查看笔记本中的单元数来检测笔记本是否是新的。但是,如果您将所有代码都写在一个单元格中,它会将其检测为新笔记本并仍会添加默认单元格。

【讨论】:

  • 这是完美的答案!不敢相信这个扩展仍然没有开箱即用。
【解决方案2】:

另一个半解决方案:将默认代码保存在文件中,然后在第一个单元格中手动键入并执行 %load 命令。

我将标准导入保存在 firstcell.py 中:

%reload_ext autoreload
%autoreload 2

import numpy as np
import pandas as pd
... 

然后在每个新笔记本中,我在第一个单元格中键入并运行%load firstcell.py,jupyter 将第一个单元格内容更改为

# %load firstcell.py
%reload_ext autoreload
%autoreload 2

import numpy as np
import pandas as pd

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

如果你真的只想要一个 import 语句,这不会给你任何东西,但如果你有几个你总是想使用,这可能会有所帮助。

【讨论】:

  • 我认为这个答案很好用。您也可以将它与我建议的那个结合起来,以便它加载写入导入的文件的路径%load firstcell.py
  • 这非常好,因为代码在运行%load 魔术后实际上已加载到单元格中
【解决方案3】:

去那里:

~/.ipython/profile_default/startup/

您可以阅读自述文件:

这是 IPython 启动目录

此目录中的

.py 和 .ipy 文件将在任何代码之前运行 或通过 exec_lines 或 exec_files 可配置文件指定的文件 每当您加载此配置文件时。

文件将按字典顺序运行,因此您可以控制 带前缀的文件的执行顺序,例如::

00-first.py
50-middle.py
99-last.ipy

所以你只需要在那里创建一个像00_imports.py 这样的文件,其中包含:

import numpy as np

如果你想添加%matplotlib inline 之类的东西,请使用.ipy,你也可以直接使用。

另外,notebook extension 似乎存在另一个解决方案,但我不知道它是如何工作的,请参阅此处以获取该主题的 github 问题: https://github.com/jupyter/notebook/issues/640

HTH

【讨论】:

  • 我猜这会将笔记本绑定到您的系统。在不同的机器上执行 notebook 会导致错误。这可能不是一个好的解决方案,因为无法再共享笔记本。
  • @jeanrjc 感谢您的想法!然而,@cel 正是我的意思。这将生成难以移植的代码,除非在 00-first.py 中记录所有隐式导入。这就是为什么我想要的是,对于我开始的每一个新的 python 笔记本,第一个单元格已经填充了一些特定的代码。
  • @jrjc 笔记本应该是自给自足和自包含的,尤其是当它们最终在 github 上或以不同方式共享时。您建议将基本代码放在单独的文件中,隐藏在某人的 homedir 中。这会导致错误。错误“No module scipy”是可以的,因为它清楚地建议安装 scipy,但是错误“imread not found”因为from scipy.misc import imread 没有共享,所以不行。
【解决方案4】:

我想出了这个:

1 - 创建一个将检查 .jupyternotebookrc 文件的启动脚本:

# ~/.ipython/profile_default/startup/run_jupyternotebookrc.py

import os
import sys

if 'ipykernel' in sys.modules: # hackish way to check whether it's running a notebook
    path = os.getcwd()
    while path != "/" and ".jupyternotebookrc" not in os.listdir(path):
        path = os.path.abspath(path + "/../")
    full_path = os.path.join(path, ".jupyternotebookrc")
    if os.path.exists(full_path):
        get_ipython().run_cell(open(full_path).read(), store_history=False)

2 - 在您的项目中使用您要运行的代码创建一个配置文件:

# .jupyternotebookrc in any folder or parent folder of the notebook

%load_ext autoreload
%autoreload 2
%matplotlib inline

import numpy as np

您可以提交并与其他人共享您的 .jupyternotebookrc,但他们还需要检查它的启动脚本。

【讨论】:

    【解决方案5】:

    一种快速且灵活的解决方案是创建模板笔记本,例如 一个具有特定导入的 python 2.7 内核的笔记本:

    a_template_for_python27.ipynb

    另一个具有不同导入的笔记本:

    a_template_for_python36.ipynb

    前面的a_ 的优点是你的笔记本显示在顶部。

    现在您可以在需要时复制笔记本。与%load firstcell.py 相比的优势在于您不需要其他文件。

    但是,这种方法的问题在于,当您想要使用另一个内核启动现有笔记本时,导入不会动态更改。

    【讨论】:

      【解决方案6】:

      在研究同一个问题时,我发现了 Jupytemplate 项目,我正在研究同一个问题,并为此类问题找到了一个非常好的 lightwightb 解决方案。当您初始化模板或按下按钮时,Jupytemplate 会将模板 Notebook 复制到您正在处理的笔记本上。之后插入的单元格是您笔记本的一个完全正常的部分,可以像使用任何其他笔记本一样进行编辑/转换/下载/导出/导入。

      Github Project jupytemplate

      【讨论】:

        【解决方案7】:

        我发现一个非常方便的替代方法是在你的笔记本中使用 %load 命令。

        作为示例,我将以下一行代码存储到 python 文件 __JN_init.py

        import numpy as np
        

        然后,只要你需要它,你就可以输入:

        %load __JN_init.py
        

        并运行单元格。您将获得要加载的预期包。优点是您可以保留一组常用的初始化代码,几乎没有时间设置。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-04
          • 2016-01-14
          • 1970-01-01
          • 2017-10-21
          • 2017-02-27
          • 2020-05-05
          • 2020-04-02
          • 1970-01-01
          相关资源
          最近更新 更多