python - 使用 jupyter nbconvert 在不同的目录中运行 jupyter notebook
问题描述
我的笔记本有一个目录结构:
- 主文件
- 笔记本/
- 笔记本.py
- 笔记本.ipynb
notebook.py 文件和 notebook.ipynb 文件与 JupyText 链接:我们将 .py 文件保存在源代码控制中(没有输出或元数据),我们将 .ipynb 文件用作常规笔记本。IntelliJ 让我们有机会从两个文件中运行单元,但不幸的是,使用不同的工作目录。这意味着引用文件变得非常头疼,因为相对路径以 ./ 或 ../ 开头
为了解决这个问题,我做了一个肮脏的 hack:在根级别(在 main.py 旁边)我定义了一个具有以下功能的 project_root.py:
def get_project_root() -> str:
return str(Path(__file__).parent)
然后,从笔记本上,我可以这样做:
from project_root import get_project_root
os.chdir(get_project_root())
突然间,工作目录始终是项目根文件夹,这意味着所有文件路径也都是相对于根文件夹的,我的头疼消失了。
输入 main.py。我已经为流程的每个步骤设置了笔记本,因此一个用于加载数据的笔记本、一个用于预处理的笔记本、一个用于分析的笔记本、一个用于我要训练的每个模型的笔记本等。这样做是因为有多个较小的文件比一个大文件更容易协作,而且东西更容易找到。
在我的主文件中,我基本上是这样做的:(删节)
def run(notebook_path: str):
os.system("jupyter nbconvert --execute {notebook_path}")
run("notebooks/notebook.ipynb")
这样,我可以以自动化的方式运行整个工作流程并测试多个参数或模型或其他任何东西。
但是该jupyter nbconvert
路径的工作目录是notebooks/
:( 如果 project_root.py 技巧有效,这会很好,但显然,它也找不到要导入的我的 python 文件。
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-1-b3b128d3ca4d> in <module>
3 print(os.getcwd()) # prints "~/project-root/notebooks"
4
----> 5 from project_root import get_project_root
6 os.chdir(get_project_root())
7 import numpy as np
ModuleNotFoundError: No module named 'project_root'
如果我可以修改jupyter nbconvert
命令的工作目录,或者如果我能以某种方式让 python 导入以另一种(可扩展的)方式工作,我的问题将得到解决。当然,欢迎任何其他建议。
亲爱的读者,谢谢您的宝贵时间!
解决方案
感谢 Sergey K. 的评论,他让我走上了正轨。
我确实将我的项目根目录标记为源文件夹,但这并没有像我希望的那样将该文件夹添加到 PYTHONPATH 中。我注意到在做之前run ("notebooks/notebook.ipynb")
,我的路径是这样的[a, b, c, d, project_root]
:但是当我进入笔记本时,我的路径是[project_root/notebooks, a, b, c, d]
,所以它要么使用单独的路径,要么删除当前工作目录并在前面添加一个新目录。
在一个肢体上,我project_root
以编程方式添加到 PYTHONPATH,它也开始出现在我笔记本中的路径中。这解决了我的问题。
总结:在 中main.py
,运行一次(我每次 IDE 启动,我想知道为什么):
from project_root import get_project_root
if get_project_root() not in os.environ['PYTHONPATH'].split(os.pathsep):
os.environ['PYTHONPATH'] = os.environ['PYTHONPATH'] + os.pathsep + get_project_root()
推荐阅读
- python - 如何将巨大的 python 列表存储为文件,然后在 python 中将文件作为列表读取?
- tableau-api - 无法在 Tableau 上从 Athena 获取数据
- javascript - 调用后如何将隐藏输入的值设置为函数的值?
- postgresql - 有没有办法合并这些 json 聚合?
- perl - “;”的意义是什么 为 perl 子例程定义形式参数时?
- html - 取消离子搜索栏中的框阴影
- amazon-web-services - 从 EC2 访问受 IP 限制的外部服务
- google-apps-script - 公式编号和脚本编号文字中的 Google 表格逗号?
- python - Python 解包问题(意外行为)
- swift - 如何使用 SwiftUI 在警报中使用导航