代码之家  ›  专栏  ›  技术社区  ›  JeremyDouglass

Jupyter可以在Python笔记本中运行单独的R笔记本吗?

  •  6
  • JeremyDouglass  · 技术社区  · 7 年前

    我有一个Jupyter笔记本(python3),这是一个批处理作业——它运行三个单独的python3笔记本,使用 %run . 我想从我的批处理中调用第四个Jupyter R内核笔记本。

    有没有办法从Jupyter/iPython中的Python笔记本执行外部R笔记本?

    当前设置:

    run_all.ipynb :(python3内核)

    %run '1_py3.ipynb'
    %run '2_py3.ipynb'
    %run '3_py3.ipynb'
    %run '4_R.ipynb'
    

    三台python3笔记本运行正常。当在Jupyter中单独打开时,R notebook可以正常运行——但是当使用 %运行 从…起 全部运行。ipynb . 它被解释为python,单元格在第一行给出python错误:

    cacheDir <- "caches"
    

    TypeError:一元操作数类型错误-:“str”

    我对从python笔记本运行单独的R笔记本的任何解决方案都感兴趣——Jupyter magic、shell、python库等等。我还对一种变通方法感兴趣,例如一种方法(如shell脚本),它可以运行所有四台笔记本电脑(包括python3和R),即使这不能在python3笔记本内完成。

    (注意:我已经了解如何嵌入 %%R 在牢房里。这不是我想要做的。我想称之为一个完全独立的R笔记本。)

    2 回复  |  直到 7 年前
        1
  •  6
  •   Louise Davies    7 年前

    我认为你不能使用 %run 当它在当前内核中执行文件时,以这种方式执行magic命令。

    Nbconvert有一个执行API,允许您执行笔记本电脑。因此,您可以创建一个shell脚本来执行所有笔记本,如下所示:

    #!/bin/bash
    jupyter nbconvert --to notebook --execute 1_py3.ipynb
    jupyter nbconvert --to notebook --execute 2_py3.ipynb
    jupyter nbconvert --to notebook --execute 3_py3.ipynb
    jupyter nbconvert --to notebook --execute 4_R.ipynb
    

    因为你的笔记本电脑不需要共享状态,这应该没问题。或者,如果您真的想在笔记本中执行,可以使用execute Python API从笔记本中调用nbconvert。

    import nbformat
    from nbconvert.preprocessors import ExecutePreprocessor
    
    with open("1_py3.ipynb") as f1, open("2_py3.ipynb") as f2, open("3_py3.ipynb") as f3, open("4_R.ipynb") as f4:
        nb1 = nbformat.read(f1, as_version=4)
        nb2 = nbformat.read(f2, as_version=4)
        nb3 = nbformat.read(f3, as_version=4)
        nb4 = nbformat.read(f4, as_version=4)
    
    ep_python = ExecutePreprocessor(timeout=600, kernel_name='python3')
    #Use jupyter kernelspec list to find out what the kernel is called on your system
    ep_R = ExecutePreprocessor(timeout=600, kernel_name='ir')
    
    # path specifies which folder to execute the notebooks in, so set it to the one that you need so your file path references are correct
    ep_python.preprocess(nb1, {'metadata': {'path': 'notebooks/'}})
    ep_python.preprocess(nb2, {'metadata': {'path': 'notebooks/'}})
    ep_python.preprocess(nb3, {'metadata': {'path': 'notebooks/'}})
    ep_R.preprocess(nb4, {'metadata': {'path': 'notebooks/'}})
    
    with open("1_py3.ipynb", "wt") as f1, open("2_py3.ipynb", "wt") as f2, open("3_py3.ipynb", "wt") as f3, open("4_R.ipynb", "wt") as f4:
        nbformat.write(nb1, f1)
        nbformat.write(nb2, f2)
        nbformat.write(nb3, f3)
        nbformat.write(nb4, f4)
    

    请注意,这几乎只是从nbconvert execute API文档复制的示例: link

        2
  •  4
  •   JeremyDouglass    7 年前

    我能够使用 the answer 实现从python3笔记本运行R笔记本的两种解决方案。

    1.致电nbconvert ! shell命令

    添加一个简单的 python3笔记本的shell命令:

    !jupyter nbconvert --to notebook --execute r.ipynb

    笔记本看起来像这样:

    1. %run '1_py3.ipynb'
    2. %run '2_py3.ipynb'
    3. %run '3_py3.ipynb'
    4. !jupyter nbconvert --to notebook --execute 4_R.ipynb

    这似乎简单易用。

    将其添加到批处理笔记本中的单元格:

    import nbformat
    from nbconvert.preprocessors import ExecutePreprocessor
    
    rnotebook = "r.ipynb"
    rnotebook_out = "r_out.ipynb"
    rnotebook_path = '/home/jovyan/work/'
    
    with open(rnotebook) as f1:
        nb1 = nbformat.read(f1, as_version=4)
    
    ep_R = ExecutePreprocessor(timeout=600, kernel_name='ir')
    ep_R.preprocess(nb1, {'metadata': {'path': rnotebook_path}})
    
    with open(rnotebook_out, "wt") as f1:
        nbformat.write(nb1, f1)
    

    这是基于Louise Davies的回答(基于nbcovert docs示例),但它只处理一个文件——非R文件可以在单独的单元格中处理,并使用 %run .

    如果批处理笔记本与其正在执行的笔记本位于同一文件夹中,则可以使用 %pwd shell magic,返回批处理笔记本的路径。

    当我们使用nbformat时。write我们可以在替换原始笔记本(方便直观,但可能会损坏或破坏文件)和创建新的输出文件之间进行选择。如果不需要单元格输出(例如,在处理文件和写入日志的工作流中),第三种选择是完全忽略写入单元格输出。

    这两种方法的一个缺点是,它们不会将单元格结果通过管道传回主笔记本显示器,这与传统方法相反 %运行 在笔记本的结果单元格中显示笔记本的输出。这个 !jupyter nbconvert import nbconvert 这个方法什么也没告诉我。