社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
本公众号已经改版,推出了线上线下课程,并且推出免费2个月广告服务业界优质产品。
彩蛋:作者著作:《Python Data Science Handbook》
上述图书是电子书链接,供爱学习的同学学习。
对于使用Jupyter notebook的户来说,你会经常遇到下面的问题:
我安装了软件包X,现在我无法将其导入到notebook中。帮帮我!
这个问题几乎是所有初学者第一个拦路虎,任何语言都是如此。今天我们就来说说Jupyter notebook如何解决这类问题。
从根本上来说,这个问题的根是Jupyter内核与Jupyter的shell分离的事实,换句话说,安装程序与笔记本中默认使用的是不同的Python版本。在最简单的情况下,这个问题不会出现,但是当调试代码时,需要了解操作系统的复杂性、Python软件包安装的复杂性以及Jupyter本身的复杂性。
在了解了一些在线(A,B)和一些关于这个话题的讨论,我决定在这里深入讨论这个问题。这篇文章将解决一些事情:
· 首先,我为一般问题提供一个快速,简单的答案,例如我如何安装一个Python包,以便使用pip或conda与我的jupyter笔记本一起工作。
· 其次,我将深入到Jupyter笔记本抽象是干什么的,如何将其与操作系统的复杂交互简单化。
· 第三,我将讨论一些我在社区的想法,其中包括Jupyter,Pip和Conda开发人员可能考虑的一些变化,以减轻用户的认知负担。
本文将重点介绍两种安装Python软件包的方法:pip和conda。
1.如何在Jupyter中安装软件包
Pip和conda
对于许多用户来说,pip和conda之间的选择可能是一个令人困惑的选择,我总结了两者之间的本质区别在于:
Pip可以在任何环境下安装python软件包。
conda在conda环境中安装任何软件包。
· 如果您使用Anaconda conda
安装Python ,则使用安装Python软件包。如果conda告诉你所需的软件包不存在,那么你必须使用pip。
即使你在短期内可以解决问题,也可能会出现长期的问题。例如,如果pip install
给你一个权限错误,这可能意味着你正在试图在系统中安装/更新python软件包,比如/usr/bin/python
。这样做会产生不好的后果,因为操作系统本身通常依赖于Python安装中的特定版本。对于Python的日常使用,你应该使用虚拟环境或Anaconda把你的软件包与系统Python隔离。
1.1:如何使用Conda在Jupyter中
如果您使用的是jupyter,并且想要使用conda安装软件包,则可能会使用!
记号直接从Jupyter上运行conda作为shell命令:
# DON'T DO THIS!!conda install --yes numpyFetching package metadata ...........Solving package specifications: .# All requested packages already installed.# packages in environment at /Users/jakevdp/anaconda/envs/python3.6:#numpy 1.13.3 py36h2cdce51_0
我将在下面更全面地概述,如果您想从当前的jupyter中使用这些已安装的软件包。
这是一个在一般情况下出现的对话:
# Install a conda package in the current Jupyter kernelimport sys!conda install --yes --prefix {sys.prefix} numpyFetching package metadata ...........Solving package specifications: .# All requested packages already installed.# packages in environment at /Users/jakevdp/anaconda:#numpy 1.13.3 py36h2cdce51_0
这个方法使得conda在当前运行的Jupyter内核中安装软件包。
1.2:如何使用pip在Jupyter中
如果您使用的是Jupyter,并想安装一个软件包pip
,您可能会倾向于直接运行pip:
# DON'T DO THIS!pip install numpyRequirement already satisfied: numpy in /Users/jakevdp/anaconda/envs/python3.6/lib/python3.6/site-packages
如果您想从当前的jupyter中使用这些已安装的软件包。
# Install a pip package in the current Jupyter kernelimport sys!{sys.executable} -m pip install numpyRequirement already satisfied: numpy in /Users/jakevdp/anaconda/lib/python3.6/s
如果你想要在Jupyter中直接使用,指令应该是:
$ python -m pip install <package>
而不是:
$ pip install <package>
因为前者更明确地说明了软件包的安装位置(下面会详细介绍)。
2.为什么Jupyter的安装如此混乱?
上述的方案应该在所有情况下都能正常工作,但为什么还需要额外的方法?这是因为在Jupyter中,shell环境和Python可执行文件是断开的。想要深入理解理解为什么,你就必须要对以下的概念有了解:
您的操作系统如何查找可执行程序。
Python如何安装和查找软件包。
Jupyter如何决定使用哪个Python可执行文件。
注意:下面的讨论假设操作系统是Linux,Unix,MacOSX。
2.1您的操作系统如何定位可执行文件?
当您正在使用的终端输入如下命令python
,jupyter
,ipython
,pip
,conda
,你的操作系统包含一个定义良好的机制,他可以找到可执行文件的名称。
在Linux和Mac系统上,系统将首先检查与命令匹配的别名,如果失败,则引用$PATH
环境变量:
!echo $PATH/Users/jakevdp/anaconda/envs/python3.6/bin:/Users/jakevdp/anaconda/envs/python3.
$PATH列出目录,按顺序,将搜索任何可执行文件:例如,如果我python在上面键入我的系统$PATH,它将首先查找/Users/jakevdp/anaconda/envs/python3.6/bin/python,如果不存在,它将查找/Users/jakevdp/anaconda/bin/python,依此类推。
2.2Python如何查找包
Python使用类似的机制来定位导入的包。Python在导入时搜索的路径列表位于:
默认情况下,Python查找模块的第一个地方是一个空路径,即当前的工作目录。如果没有找到该模块,则将它放在位置列表中,直到找到该模块。您可以使用__path__
导入的模块的属性找出哪个位置已被使用:
import numpynumpy.__path__['/Users/jakevdp/anaconda/lib/python3.6/site-packages/numpy']
在大多数情况下,你安装了Python包pip或conda将被放置在一个名为目录site-packages。要认识到的重要一点是每个Python可执行文件都有自己的site-packages。这意味着当你安装一个软件包时,它与特定的python可执行文件相关联,并且默认只能用于Python安装。
我们可以打印sys.path每个可用python可执行文件的变量来看到这一点,使用Jupyter令人愉快的是将Python和bash命令混合在一个代码块中的功能:
paths = !type -a pythonfor path in set(paths): path = path.split()[-1] print(path) !{path} -c "import sys; print(sys.path)" print()
这里的全部细节并不是特别重要,但是需要强调的是,每个Python可执行文件都有自己独特的路径,除非您修改sys.path,否则不能导入安装在不同Python环境中的软件包。
我将再次强调:Jupyter中的shell环境必须与启动它的Python版本相匹配。
2.3: Jupyter如何执行代码:Jupyter内核
下一个相关的问题是Jupyter如何选择执行Python代码,这使我们想到了Jupyter内核的概念。
Jupyter内核是指Jupyter在内执行代码的一系列文件。对于Python内核,这将指向一个特定的Python版本,但Jupyter被设计得更通用:Jupyter有几十个可用的内核,包括Python 2,Python 3,Julia,R,Ruby,Haskell,甚至C ++和Fortran。
如果您使用Jupyter,则可以随时使用内核→选择内核菜单项来更改内核。
要查看您的系统上可用的内核,可以在shell中运行以下命令:
!jupyter kernelspec listAvailable kernels: python3 /Users/jakevdp/anaconda/envs/python3.6/lib/python3.6/site-packages/ipykernel/resources conda-root /Users/jakevdp/Library/Jupyter/kernels/conda-root python2.7 /Users/jakevdp/Library/Jupyter/kernels/python2.7 python3.5 /Users/jakevdp/Library/Jupyter/kernels/python3.5 python3.6 /Users/jakevdp/Library/Jupyter/kernels/python3.6
这些列出的内核中的每一个都是一个包含名为kernel.json
的文件的目录,其中指定了内核应该使用哪种语言和可执行文件。例如:
!cat /Users/jakevdp/Library/Jupyter/kernels/conda-root/kernel.json{ "argv": [ "/Users/jakevdp/anaconda/bin/python", "-m", "ipykernel_launcher", "-f", "{connection_file}" ], "display_name": "python (conda-root)", "language": "python"}
如果你想创建一个新的内核,可以使用jupyter ipykernel命令来完成。例如,我使用以下内容作为模板,为我的conda环境创建了上述内核:
$ source activate myenv$ python -m ipykernel install --user --name myenv --display-name "Python (myenv)"
3.一些建议
所以,综上所述,安装在Jupyter的包是从根本上说Jupyter的shell环境和Python的内核不匹配,这意味着你必须做的不是简单地多了解pip install
或conda install
做事情的工作。
我有一些想法,其中一些可能是有用的:
3.1:Jupyter 的潜在策略
正如我所提到的,根本问题是Jupyter的shell环境和计算内核之间的不匹配。那么,我们是否可以按照内核规范来强制二者匹配呢?
也许,这个github问题展示了一种在内核启动时修改shell变量的方法。
基本上,在你的内核目录中,你可以添加一个如下所示的脚本kernel-startup.sh
(并确保你改变了权限以便它是可执行的):
#!/usr/bin/env bash# activate anaconda envsource activate myenv# this is the critical part, and should be at the end of your script:exec python -m ipykernel $@
3.2新的Jupyter Magic函数
我们可以通过在Jupyter中引入%pip
和%conda
魔术功能来简化用户体验,从而检测当前的内核并使某些软件包安装在正确的位置。
PIP Magic
例如,下面是如何定义一个%pip
在当前内核中工作的魔术函数:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!