Pythonの依存関係管理:どのツールを選ぶべきですか?
Python dependency management which tool should you choose?
Poetry、Pip、およびCondaの詳細な比較
オリジナルの記事は2023年6月13日にhttps://mathdatasimplified.comで公開されました。
動機
データサイエンスプロジェクトが拡大するにつれて、依存関係の数も増えてきます。プロジェクトの環境を再現可能でメンテナブルに保つために、効率的な依存関係管理ツールを使用することが重要です。
したがって、依存関係管理のための3つの人気ツール、Pip、Conda、Poetryを比較することにしました。慎重な評価の結果、Poetryが効果的でパフォーマンスに優れていると結論づけられました。
この記事では、Poetryの利点について詳しく説明し、PipやCondaとの主な違いを強調します。
- 注目すべきプラグイン:データ分析を自動化するChatGPTプラグイン
- LLMsによる非構造化データから構造化データへの変換
- データサイエンスプロジェクトでのハードコーディングをやめましょう – 代わりに設定ファイルを使用しましょう
利用可能なパッケージ
多数のパッケージがあると、開発者が特定のパッケージやバージョンを見つけやすくなります。
Conda
「snscrape」などの一部のパッケージはcondaでインストールできません。また、Pandas 2.0などの特定のバージョンがCondaを介してインストールできない場合があります。
conda仮想環境内でpipを使用してパッケージの制限に対処することはできますが、pipでインストールされた依存関係をcondaが追跡できないため、依存関係の管理が困難になります。
$ conda list# packages in environment at /Users/khuyentran/miniconda3/envs/test-conda:## Name Version Build Channel$ conda list # packages in environment at /Users/khuyentran/miniconda3/envs/test-conda: # # Name Version Build Channel
Pip
Pipは、Python Package Index(PyPI)および他のリポジトリから任意のパッケージをインストールできます。
Poetry
PoetryもPython Package Index(PyPI)および他のリポジトリからパッケージをインストールできます。
依存関係の数
環境内の依存関係の数を減らすことで、開発プロセスがシンプルになります。
Conda
Condaは完全な環境の分離を提供し、Pythonパッケージとシステムレベルの依存関係の両方を管理します。これにより、他のパッケージマネージャーに比べてパッケージサイズが大きくなる可能性があり、インストールおよび配布中により多くのストレージスペースを消費する可能性があります。
$ conda install pandas$ conda list # packages in environment at /Users/khuyentran/miniconda3/envs/test-conda:## Name Version Build Channel blas 1.0 openblas bottleneck 1.3.5 py311ha0d4635_0 bzip2 1.0.8 h620ffc9_4 ca-certificates 2023.05.30 hca03da5_0 libcxx 14.0.6 h848a8c0_0 libffi 3.4.4 hca03da5_0 libgfortran 5.0.0 11_3_0_hca03da5_28 libgfortran5 11.3.0 h009349e_28 libopenblas 0.3.21 h269037a_0 llvm-openmp 14.0.6 hc6e5704_0 ncurses 6.4 h313beb8_0 numexpr 2.8.4 py311h6dc990b_1 numpy 1.24.3 py311hb57d4eb_0 numpy-base 1.24.3 py311h1d85a46_0 openssl 3.0.8 h1a28f6b_0 pandas 1.5.3 py311h6956b77_0 pip 23.0.1 py311hca03da5_0 python 3.11.3 hb885b13_1 python-dateutil 2.8.2 pyhd3eb1b0_0 pytz 2022.7 py311hca03da5_0 readline 8.2 h1a28f6b_0 setuptools 67.8.0 py311hca03da5_0 six 1.16.0 pyhd3eb1b0_1 sqlite 3.41.2 h80987f9_0 tk 8.6.12 hb8d0fd4_0 tzdata 2023c h04d1e81_0 wheel 0.38.4 py311hca03da5_0 xz 5.4.2 h80987f9_0 zlib 1.2.13 h5a0b063_0
Pip
Pipはパッケージに必要な依存関係のみをインストールします。
$ pip install pandas$ pip listPackage Version--------------- -------numpy 1.24.3pandas 2.0.2pip 22.3.1python-dateutil 2.8.2pytz 2023.3setuptools 65.5.0six 1.16.0tzdata 2023.3
Poetry
Poetryはパッケージに必要な依存関係のみをインストールします。
$ poetry add pandas$ poetry shownumpy 1.24.3 Pythonでの配列計算の基盤的なパッケージpandas 2.0.2 データ解析のための強力なデータ構造、時間...python-dateutil 2.8.2 Python標準のdatetimeモジュールの拡張pytz 2023.3 現代および歴史的な世界のタイムゾーン定義six 1.16.0 Python 2と3の互換性ツールtzdata 2023.3 IANAタイムゾーンデータの提供者
パッケージのアンインストール
パッケージとその依存関係をアンインストールすることで、ディスクスペースを解放し、不要なクラッターを防止し、ストレージリソースの使用を最適化できます。
Pip
Pipは指定されたパッケージのみを削除しますが、その依存関係は削除されません。これにより、未使用の依存関係が増え、ストレージスペースの使用量が増加し、競合が発生する可能性があります。
$ pip install pandas$ pip uninstall pandas$ pip listPackage Version--------------- -------numpy 1.24.3pip 22.0.4python-dateutil 2.8.2pytz 2023.3setuptools 56.0.0six 1.16.0tzdata 2023.3
Conda
Condaはパッケージとその依存関係を削除します。
$ conda install -c conda pandas$ conda uninstall -c conda pandasCollecting package metadata (repodata.json): doneSolving environment: done## Package Plan ## environment location: /Users/khuyentran/miniconda3/envs/test-conda removed specs: - pandasThe following packages will be REMOVED: blas-1.0-openblas bottleneck-1.3.5-py311ha0d4635_0 libcxx-14.0.6-h848a8c0_0 libgfortran-5.0.0-11_3_0_hca03da5_28 libgfortran5-11.3.0-h009349e_28 libopenblas-0.3.21-h269037a_0 llvm-openmp-14.0.6-hc6e5704_0 numexpr-2.8.4-py311h6dc990b_1 numpy-1.24.3-py311hb57d4eb_0 numpy-base-1.24.3-py311h1d85a46_0 pandas-1.5.3-py311h6956b77_0 python-dateutil-2.8.2-pyhd3eb1b0_0 pytz-2022.7-py311hca03da5_0 six-1.16.0-pyhd3eb1b0_1Proceed ([y]/n)? Preparing transaction: doneVerifying transaction: doneExecuting transaction: donePoetry
Poetry
Poetryもパッケージとその依存関係を削除します。
$ poetry add pandas$ poetry remove pandas • Removing numpy (1.24.3) • Removing pandas (2.0.2) • Removing python-dateutil (2.8.2) • Removing pytz (2023.3) • Removing six (1.16.0) • Removing tzdata (2023.3)
依存関係ファイル
依存関係ファイルは、必要なパッケージの正確なバージョンまたはバージョン範囲を指定することで、ソフトウェアプロジェクトの環境の再現性を確保します。
これにより、異なるシステムまたは異なる時点で同じ環境を再現し、同じ依存関係を持つ開発者間の協力を保証できます。
Conda
Conda環境で依存関係を保存するには、手動でファイルに書き込む必要があります。 environment.ymlファイルで指定されたバージョン範囲により、異なるバージョンがインストールされる可能性があり、環境を再現する際に互換性の問題が発生することがあります。
例として、pandasバージョン1.5.3をインストールしたと仮定します。 これは、依存関係を指定する例のenvironment.ymlファイルです:
# environment.ymlname: test-condachannels: - defaultsdependencies: - python=3.8 - pandas>=1.5
最新バージョンのpandasが2.0の場合、新しいユーザーが環境を再現しようとすると、pandas 2.0がインストールされます。
# 仮想環境を作成してアクティブ化する$ conda env create -n env$ conda activate env# 現在の環境のパッケージをリスト表示する$ conda list...pandas 2.0
コードベースがpandasバージョン1.5.3に固有の構文または動作に依存しており、構文がバージョン2.0で変更されている場合、pandas 2.0でコードを実行するとバグが発生する可能性があります。
Pip
同じ問題がpipでも発生する可能性があります。
# requirements.txt pandas>=1.5
# 仮想環境を作成してアクティブ化する$ python3 -m venv venv$ source venv/bin/activate# 依存関係をインストールする$ pip install -r requirements.txt# パッケージをリスト表示する$ pip listPackage Version---------- -------pandas 2.0
バージョンを固定するには、requirements.txtファイルにフリーズさせることができます:
$ pip freeze > requirements.txt
# requirements.txtnumpy==1.24.3pandas==1.5.3python-dateutil==2.8.2pytz==2023.3six==1.16.0
しかし、これによりコード環境が柔軟性を欠き、長期的にはメンテナンスが困難になる可能性があります。 依存関係に変更が加えられるたびに、手動でrequirements.txtファイルを変更する必要があり、時間がかかったりエラーを起こす可能性があります。
Poetry
Poetryは、パッケージをインストールするときにpyproject.tomlファイルを自動的に更新します。
次の例では、「pandas」パッケージがバージョン制約^1.5
で追加されています。この柔軟なバージョン管理の方法により、手動での調整なしにプロジェクトを新しいリリースに適応できます。
$ poetry add 'pandas=^1.5'
# pyproject.toml[tool.poetry.dependencies]python = "^3.8"pandas = "^1.5"
poetry.lockファイルには、各パッケージとその依存関係の正確なバージョン番号が格納されます。
# poetry.lock...[[package]]name = "pandas"version = "1.5.3"description = "Powerful data structures for data analysis, time series, and statistics"category = "main"optional = falsepython-versions = ">=3.8"[package.dependencies]numpy = [ {version = ">=1.20.3", markers = "python_version < \"3.10\""}, {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, {version = ">=1.23.2", markers = "python_version >= \"3.11\""},]python-dateutil = ">=2.8.2"pytz = ">=2020.1"tzdata = ">=2022.1"...
これにより、pyproject.tomlファイルでバージョン範囲が指定されている場合でも、インストールされるパッケージの一貫性が保証されます。ここでは、pandas 1.5.3がインストールされていることがわかります。
$ poetry install$ poetry show pandasname : pandas version : 1.5.3 description : Powerful data structures for data analysis, time series, and statistics dependencies - numpy >=1.20.3 - numpy >=1.21.0 - numpy >=1.23.2 - python-dateutil >=2.8.1 - pytz >=2020.1
開発と本番用の依存関係を分離する
依存関係を分離することで、開発目的(テストフレームワークやコード品質ツールなど)に必要なパッケージと、本番環境に必要なコア依存関係とを明確に区別できます。
Conda
Condaは本来別々の環境に対応していないため、開発環境と本番環境の2つの環境ファイルを作成する回避策があります。開発ファイルには、本番依存関係と開発依存関係の両方が含まれます。
# environment.ymlname: test-condachannels: - defaultsdependencies: # 本番パッケージ - numpy - pandas
# environment-dev.ymlname: test-conda-devchannels: - defaultsdependencies: # 本番パッケージ - numpy - pandas # 開発パッケージ - pytest - pre-commit
Pip
Pipも別々の依存関係を直接サポートしていませんが、別々の要件ファイルを使用した同様のアプローチが使用できます。
# requirements.txtnumpy pandas
# requirements-dev.txt-r requirements.txtpytestpre-commit
# 本番のみをインストール$ pip install -r requirements.txt# 開発と本番の両方をインストール$ pip install -r requirements-dev.txt
Poetry
Poetryは、1つのファイル内でグループをサポートすることで依存関係の管理を簡素化します。これにより、すべての依存関係を1か所に集めることができます。
$ poetry add numpy pandas$ poetry add --group dev pytest pre-commit
# pyproject.toml[tool.poetry.dependencies]python = "^3.8"pandas = "^2.0"numpy = "^1.24.3"[tool.poetry.group.dev.dependencies]pytest = "^7.3.2"pre-commit = "^3.3.2"
本番の依存関係のみをインストールするには:
$ poetry install --only main
開発と本番の両方の依存関係をインストールするには:
$ poetry install
環境の更新
依存関係の更新は、バグ修正、パフォーマンスの改善、および新しいパッケージバージョンで導入された新機能の利点を得るために重要です。
Conda
Condaを使用すると、指定されたパッケージのみを更新できます。
$ conda install -c conda pandas$ conda install -c anaconda scikit-learn
# 新しいバージョンが利用可能です$ conda update pandas$ conda update scikit-learn
その後、更新された依存関係と同期させるために、environment.yamlファイルを手動で更新する必要があります。
$ conda env export > environment.yml
Pip
Pipも指定されたパッケージのみを更新でき、要件.txtファイルを手動で更新する必要があります。
$ pip install -U pandas
$ pip freeze > requirements.txt
Poetry
Poetryを使用すると、pyproject.tomlファイルで指定されたすべてのパッケージをアップグレードするためにupdate
コマンドを使用できます。この操作により、パッケージの仕様とロックファイルの間の一貫性が確保されるように、poetry.lockファイルが自動的に更新されます。
$ poetry add pandas scikit-learn# 新しいバージョンが利用可能ですpoetry update依存関係を更新中... (0.3s)ロックファイルを書き込み中: パッケージ操作: 0個のインストール、2個の更新、0個の削除 • pandasを更新中 (2.0.0 -> 2.0.2) • scikit-learnを更新中 (1.2.0 -> 1.2.2)
依存関係の解決
プロジェクトで必要なパッケージやライブラリに矛盾するバージョンや非互換な依存関係がある場合、依存関係の解決はエラーや実行時の問題、プロジェクトの失敗を回避するために重要です。
Pip
pipはパッケージを順次インストールするため、指定された順序に従って1つずつパッケージをインストールします。この順次アプローチは、パッケージに非互換な依存関係やバージョン要件がある場合に、時には依存関係の競合を引き起こすことがあります。
たとえば、最初にpandas==2.0.2
をインストールして、numpy>=1.20.3
を必要とする場合を考えてみましょう。その後、pipを使用してnumpy==1.20.2
をインストールします。パッケージの競合が発生しますが、pipはnumpyのバージョンを更新し続けます。
$ pip install pandas==2.0.2$ pip install numpy==1.22.2Collecting numpy=1.20.2 Attempting uninstall: numpy Found existing installation: numpy 1.24.3 Uninstalling numpy-1.24.3: Successfully uninstalled numpy-1.24.3ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.pandas 2.0.2 requires numpy>=1.20.3; python_version < "3.10", but you have numpy 1.20.2 which is incompatible.Successfully installed numpy-1.20.2
Conda
Condaは、パッケージのバージョンと依存関係のすべての組み合わせを探索して、互換性のあるセットを見つけるためにSATソルバを使用します。
たとえば、既存のパッケージが依存関係に特定の制約を持っている場合(例えば、statsmodels==0.13.2はnumpy>=1.21.2,<2.0a0を必要とする)、そしてインストールしたいパッケージがその要件を満たさない場合(例えば、numpy<1.21.2)、condaはすぐにエラーを発生させません。その代わりに、必要なすべてのパッケージとその依存関係の互換性のあるバージョンを熱心に検索して、適切な解が見つからない場合にのみエラーを報告します。
$ conda install 'statsmodels==0.13.2'$ conda search 'statsmodels==0.13.2' --infodependencies: - numpy >=1.21.2,<2.0a0 - packaging >=21.3 - pandas >=1.0 - patsy >=0.5.2 - python >=3.9,<3.10.0a0 - scipy >=1.3$ conda install 'numpy<1.21.2'...Package ca-certificates conflicts for:python=3.8 -> openssl[version='>=1.1.1t,<1.1.2a'] -> ca-certificatesopenssl -> ca-certificatesca-certificatescryptography -> openssl[version='>1.1.0,<3.1.0'] -> ca-certificatesPackage idna conflicts for:requests -> urllib3[version='>=1.21.1,<1.27'] -> idna[version='>=2.0.0']requests -> idna[version='>=2.5,<3|>=2.5,<4']idnapooch -> requests -> idna[version='>=2.5,<3|>=2.5,<4']urllib3 -> idna[version='>=2.0.0']Package numexpr conflicts for:statsmodels==0.13.2 -> pandas[version='>=1.0'] -> numexpr[version='>=2.7.0|>=2.7.1|>=2.7.3']numexprpandas==1.5.3 -> numexpr[version='>=2.7.3']Package patsy conflicts for:statsmodels==0.13.2 -> patsy[version='>=0.5.2']patsyPackage chardet conflicts for:requests -> chardet[version='>=3.0.2,<4|>=3.0.2,<5']pooch -> requests -> chardet[version='>=3.0.2,<4|>=3.0.2,<5']Package python-dateutil conflicts for:statsmodels==0.13.2 -> pandas[version='>=1.0'] -> python-dateutil[version='>=2.7.3|>=2.8.1']python-dateutilpandas==1.5.3 -> python-dateutil[version='>=2.8.1']Package setuptools conflicts for:numexpr -> setuptoolspip -> setuptoolswheel -> setuptoolssetuptoolspython=3.8 -> pip -> setuptoolspandas==1.5.3 -> numexpr[version='>=2.7.3'] -> setuptoolsPackage brotlipy conflicts for:urllib3 -> brotlipy[version='>=0.6.0']brotlipyrequests -> urllib3[version='>=1.21.1,<1.27'] -> brotlipy[version='>=0.6.0']Package pytz conflicts for:pytzpandas==1.5.3 -> pytz[version='>=2020.1']statsmodels==0.13.2 -> pandas[version='>=1.0'] -> pytz[version='>=2017.3|>=2020.1']
このアプローチは、解決策を見つける可能性を高めますが、特に広範な環境を扱う場合には計算量が大きくなることがあります。
Poetry
プロジェクトの直接の依存関係に焦点を当てることにより、Poetryの決定論的リゾルバーは検索スペースを狭め、解決プロセスをより効率的にします。指定された制約、バージョン範囲、または特定のバージョンなどを評価し、すぐに競合があるかどうかを特定します。
$ poetry add 'seaborn==0.12.2'$ poetry add 'matplotlib<3.1' Because poetry shell depends on seaborn (0.12.2) which depends on matplotlib (>=3.1,<3.6.1 || >3.6.1), matplotlib is required.So, because poetry shell depends on matplotlib (<3.1), version solving failed.
この即時フィードバックにより、潜在的な問題のエスカレーションを防ぎ、開発プロセスの早い段階で問題に対処できます。たとえば、以下のコードでは、seabornの要件を緩和して、特定のバージョンのmatplotlibをインストールできるようにできます。
poetry add 'seaborn<=0.12.2' 'matplotlib<3.1' Package operations: 1 install, 2 updates, 4 removals • Removing contourpy (1.0.7) • Removing fonttools (4.40.0) • Removing packaging (23.1) • Removing pillow (9.5.0) • Updating matplotlib (3.7.1 -> 3.0.3) • Installing scipy (1.9.3) • Updating seaborn (0.12.2 -> 0.11.2)
結論
要約すると、Poetryはpipやcondaよりもいくつかの利点を提供します。
- 広範なパッケージ選択: Poetryは、プロジェクトに多様なエコシステムを活用するためにPyPIで利用可能な幅広い範囲のパッケージにアクセスできます。
- 効率的な依存関係管理: Poetryは指定されたパッケージに必要な依存関係のみをインストールし、環境内の不要なパッケージの数を減らします。
- 簡略化されたパッケージの削除: Poetryは、パッケージとそれに関連する依存関係の削除を簡素化し、クリーンで効率的なプロジェクト環境を維持することが容易になります。
- 依存関係の解決: Poetryの決定論的リゾルバーは、依存関係を効率的に解決し、不整合や競合を迅速に特定して解決します。
Poetryは、チームメイトが学習して適応するために追加の時間と労力が必要かもしれませんが、Poetryのようなツールを使用することで、長期的に時間と労力を節約できます。
私はデータサイエンスのコンセプトについて書くことや、さまざまなデータサイエンスのツールで遊ぶことが大好きです。最新の投稿については、以下の方法で更新情報を受け取ることができます。
- Data Science Simplifiedのニュースレターに登録する
- LinkedInとTwitterで私につながる
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles