今までvenvを使ってPythonの仮想環境を作成していました。
Amazon sagemaker labではcondaが使えたので、condaも扱えるようにしようと思い「商用利用可のconda環境をMacに構築してみた (conda+conda-forge)」という記事を以前書きました。
環境構築をするだけで具体的な使い方をまとめていなかったので、condaコマンドで仮想環境を作成する方法と1つのjupyter notebookから各仮想環境のカーネルを呼び出す方法を調査しようと思います。
あと気になったのは、venvの環境とcondaの環境の両方を共存させた上でjupyter notebookの環境から呼び出せるのかは気になります。(カーネルごとに分かれているので出来るのではないかと予想はしています)
※ 結果を書くと出来ました。最終的なイメージは下記になります。
元々venvで作成してある、「my-venv」でjupyter notebookを起動し、condaコマンドを使って作成した「py38」環境のカーネルを実行させたいと思います。
それではやっていきます。
conda環境のアップデート
使っているうちにインストール済みのパッケージが古くなっていくので私は定期的にアップデートしています。
システムが特定のバージョンのライブラリに依存している場合はやってはいけませんが、バグが修正されていたり追加機能が使えることが多いので更新できる環境であれば積極的にやります。
たまにライブラリが新しくなりすぎて既存のコードが動かなるので、心配な場合はバックアップを取っておいた方がいいかも知れません。
# miniforge3利用の場合
source ~/miniforge3/bin/activate
# condaコマンドのパスが通ってる場合
conda activate
# condaコマンドのパスが通ってる場合 (特定の仮想環境に入る)
conda activate my-env
# https://docs.conda.io/projects/conda/en/latest/commands/update.html
(base) conda update conda
Collecting package metadata (current_repodata.json): done Solving environment: done ・・・省略・・・ package | build ---------------------------|----------------- ca-certificates-2022.12.7 | h033912b_0 142 KB conda-forge certifi-2022.12.7 | pyhd8ed1ab_0 147 KB conda-forge cffi-1.15.1 | py310ha78151a_3 215 KB conda-forge conda-23.1.0 | py310h2ec42d9_0 919 KB conda-forge conda-package-handling-2.0.2| pyh38be061_0 247 KB conda-forge conda-package-streaming-0.7.0| pyhd8ed1ab_1 17 KB conda-forge cryptography-39.0.2 | py310hdd0c95c_0 1.1 MB conda-forge libcxx-15.0.7 | h71dddab_0 1.1 MB conda-forge libsqlite-3.40.0 | ha978bb4_0 873 KB conda-forge openssl-3.1.0 | hfd90126_0 2.2 MB conda-forge pluggy-1.0.0 | pyhd8ed1ab_5 16 KB conda-forge pyopenssl-23.0.0 | pyhd8ed1ab_0 124 KB conda-forge python_abi-3.10 | 3_cp310 6 KB conda-forge requests-2.28.2 | pyhd8ed1ab_0 55 KB conda-forge ruamel.yaml-0.17.21 | py310h90acd4f_3 187 KB conda-forge ruamel.yaml.clib-0.2.7 | py310h90acd4f_1 115 KB conda-forge setuptools-67.6.0 | pyhd8ed1ab_0 566 KB conda-forge tqdm-4.65.0 | pyhd8ed1ab_1 86 KB conda-forge tzdata-2022g | h191b570_0 106 KB conda-forge urllib3-1.26.15 | pyhd8ed1ab_0 110 KB conda-forge wheel-0.40.0 | pyhd8ed1ab_0 54 KB conda-forge zstandard-0.19.0 | py310h3cf44b0_1 395 KB conda-forge zstd-1.5.2 | hbc0c0cd_6 399 KB conda-forge ------------------------------------------------------------ Total: 9.0 MB ・・・ Preparing transaction: done Verifying transaction: done Executing transaction: done Retrieving notices: ...working... done
まずはconda-23.1.0のパッケージだけをアップデートしようと思いましたが、関連パッケージもアップデートされるようです。--no-depsオプションをつければcondaだけアップデートされるかも知れません。
(base) conda update --update-all
Retrieving notices: ...working... done Collecting package metadata (current_repodata.json): done Solving environment: done ・・・省略・・・ The following packages will be UPDATED: pip 22.3-pyhd8ed1ab_0 --> 23.0.1-pyhd8ed1ab_0 python 3.10.6-hc14f532_0_cpython --> 3.10.9-he7542f4_0_cpython Proceed ([y]/n)? y Downloading and Extracting Packages Preparing transaction: done Verifying transaction: done Executing transaction: done
pipとpythonはcondaのアップデートの関連にはなっていないようです。ここらへんは無闇にアップデートしたくはないので、conda環境でインストール済みのライブラリをアップデートしたい場合はconda update condaが無難かも知れません。
condaで仮想環境を作成する
condaだとpythonのバージョンを指定して仮想環境を作るのがvenvより楽です。
venvだと異なるPythonのバージョンを事前にインストールしておくか、pyenvといったツールで複数のPythonを使い分ける必要があります。
pythonのバージョンを「指定する方法」と「指定しない方法」があります。
特にバージョンを気にしないのであればシステムで使っているPythonで仮想環境を作成するで問題ありません。
使いたいライブラリがあって、Pythonの推奨バージョンがあればそちらを指定することをおすすめします。
今回はpython3.8の仮想環境を作成してみます。
# https://www.python.jp/install/anaconda/conda.html#3zoyVv
# デフォルトのpythonバージョン(/usr/bin/python)で作成された
# conda create --name py-default
# pythonのバージョンを3.8に指定して仮想環境を作成
conda create --name py38 python=3.8
Collecting package metadata (current_repodata.json): done Solving environment: done ## Package Plan ## environment location: /Users/hinomaruc/miniforge3/envs/py38 added / updated specs: - python=3.8 The following packages will be downloaded: package | build ---------------------------|----------------- python-3.8.16 |hf9b03c3_1_cpython 11.8 MB conda-forge ------------------------------------------------------------ Total: 11.8 MB The following NEW packages will be INSTALLED: bzip2 conda-forge/osx-64::bzip2-1.0.8-h0d85af4_4 ca-certificates conda-forge/osx-64::ca-certificates-2022.12.7-h033912b_0 libffi conda-forge/osx-64::libffi-3.4.2-h0d85af4_5 libsqlite conda-forge/osx-64::libsqlite-3.40.0-ha978bb4_0 libzlib conda-forge/osx-64::libzlib-1.2.13-hfd90126_4 ncurses conda-forge/osx-64::ncurses-6.3-h96cf925_1 openssl conda-forge/osx-64::openssl-3.1.0-hfd90126_0 pip conda-forge/noarch::pip-23.0.1-pyhd8ed1ab_0 python conda-forge/osx-64::python-3.8.16-hf9b03c3_1_cpython readline conda-forge/osx-64::readline-8.1.2-h3899abd_0 setuptools conda-forge/noarch::setuptools-67.6.0-pyhd8ed1ab_0 tk conda-forge/osx-64::tk-8.6.12-h5dbffcc_0 wheel conda-forge/noarch::wheel-0.40.0-pyhd8ed1ab_0 xz conda-forge/osx-64::xz-5.2.6-h775f41a_0 Proceed ([y]/n)? y Downloading and Extracting Packages Preparing transaction: done Verifying transaction: done Executing transaction: done
python-3.8.16の仮想環境をcondaで作成出来たようです。便利ですね。
conda activate py38
(py38) python3 -V
Python 3.8.16
期待したPythonのバージョンです。
condaの仮想環境をjupyter notebookのカーネル一覧から選択できるようにする
仮想環境ごとにjupyter notebookをインストールして立ち上げるのは非効率なので、ipykernelをインストールして1つのjupyter notebookからカーネルを呼び出すことにより仮想環境を手軽に切り替えられるようにします。
# https://anaconda.org/anaconda/ipykernel
(py38) conda install ipykernel
Collecting package metadata (current_repodata.json): done Solving environment: done ## Package Plan ## environment location: /Users/hinomaruc/miniforge3/envs/py38 added / updated specs: - ipykernel The following packages will be downloaded: package | build ---------------------------|----------------- appnope-0.1.3 | pyhd8ed1ab_0 8 KB conda-forge asttokens-2.2.1 | pyhd8ed1ab_0 27 KB conda-forge backcall-0.2.0 | pyh9f0ad1d_0 13 KB conda-forge backports-1.0 | pyhd8ed1ab_3 6 KB conda-forge backports.functools_lru_cache-1.6.4| pyhd8ed1ab_0 9 KB conda-forge debugpy-1.6.6 | py38h4cd09af_0 1.8 MB conda-forge decorator-5.1.1 | pyhd8ed1ab_0 12 KB conda-forge executing-1.2.0 | pyhd8ed1ab_0 24 KB conda-forge importlib-metadata-6.0.0 | pyha770c72_0 24 KB conda-forge importlib_metadata-6.0.0 | hd8ed1ab_0 9 KB conda-forge ipykernel-6.15.0 | pyh736e0ef_0 96 KB conda-forge ipython-8.11.0 | pyhd1c38e8_0 568 KB conda-forge ・・・省略・・・ Executing transaction: done
(py38) python3 -m ipykernel install --user --name py38 --display-name "Conda(py38)"
(py38) jupyter kernelspec list
Available kernels: python3 /Users/hinomaruc/miniforge3/envs/py38/share/jupyter/kernels/python3 py38 /Users/hinomaruc/Library/Jupyter/kernels/py38 venv-chatgpt /Users/hinomaruc/Library/Jupyter/kernels/venv-chatgpt venv-lifegame /Users/hinomaruc/Library/Jupyter/kernels/venv-lifegame venv-oracle /Users/hinomaruc/Library/Jupyter/kernels/venv-oracle venv-prophet /Users/hinomaruc/Library/Jupyter/kernels/venv-prophet venv-scraping /Users/hinomaruc/Library/Jupyter/kernels/venv-scraping venv-sound /Users/hinomaruc/Library/Jupyter/kernels/venv-sound venv-tensorflow /Users/hinomaruc/Library/Jupyter/kernels/venv-tensorflow venv_autogluon /Users/hinomaruc/Library/Jupyter/kernels/venv_autogluon venv_autosklearn /Users/hinomaruc/Library/Jupyter/kernels/venv_autosklearn venv_mljar /Users/hinomaruc/Library/Jupyter/kernels/venv_mljar venv_opencv /Users/hinomaruc/Library/Jupyter/kernels/venv_opencv
py38というカーネルが存在することがわかります。他にもvenvで作成した仮想環境も一覧に出てきます。
jupyter notebookからcondaの仮想環境カーネルを参照する
冒頭で述べた「my-venv」環境でjupyter notebookを実行し、condaの「py38」を呼び出したいと思います。
source ~/Desktop/blog/my-venv/bin/activate
(my-venv) jupyter notebook
Conda(py38)環境がカーネル一覧に表示されています。Conda(py38)で新しいノートブックを作成してみましょう。
condaコマンドも実行できました。condaの仮想環境を使えていることが分かります。
condaとpipの併用は気を付ける
Conda(py38)の中でpip install pandasとかやっても問題ありませんが、conda installとpip installを併用すると環境がめちゃくちゃになってしまう可能性もあるため可能であればconda installに統一した方が良いようです。
具体的にはcondaはpipでインストールしたライブラリを上書きしたり壊したりしてしまう可能性があったり、pipはcondaでインストールしたライブラリをアップグレードや削除してしまう可能性があると書かれています。
Running conda after pip has the potential to overwrite and potentially break packages installed via pip. Similarly, pip may upgrade or remove a package which a conda-installed package requires.
引用: https://www.anaconda.com/blog/using-pip-in-a-conda-environment
もしcondaとpipを併用したい(しなければいけない)場合は、基本的にはconda installで必要なライブラリをインストールしてPyPIにしかないライブラリはconda-buildの機能にあるconda skeletonを使ってconda用のライブラリに変換してあげる方法がおすすめされています。
ただし、あまりにPyPIにしかないライブラリが多い場合は、--upgrade-strategy only-if-neededオプションを追加して本当にPyPIにしかないライブラリを最後にインストールしてあげるのが良いようです。
If software is needed which is not available as a conda package, conda build can be used to create packages ... For projects available on PyPI, the conda skeleton command ... produces a recipe which can be used create a conda package with little or no modifications.
using pip only after all other requirements have been installed via conda is the safest practice. Additionally, pip should be run with the “--upgrade-strategy only-if-needed”
引用: https://www.anaconda.com/blog/using-pip-in-a-conda-environment
既存の環境を壊してしまう懸念がある場合はconda create --name py38bk --clone py38コマンドで事前に仮想環境のコピーを取得しておきましょう
conda環境の中でpipを使うベストプラクティスに関しては「Using Pip in a Conda EnvironmentUsing Pip in a Conda Environment」に記載があります。
また、stackoverflowにも「Is that a bad idea to use conda and pip install on the same environment?」という記事があり参考になりました。
まとめ
condaの扱い方をまとめることができてすっきりしています。個人的にはpipがPythonのデフォルトパッケージマネジャーとして使われているので正統派な気がして好んで使い続けてきました。ただ、個人での研究や分析利用で何も制約がないのであればpython環境も管理できるcondaの方が使いやすくていいなと思います。
pipとcondaの比較に関しては「What is the difference between pip and conda」に分かりやすくまとまっているのでおすすめです。