ModuleNotFoundError для «sklearn» как подзависимость от numpy

Я использую Docker в сочетании с virtualenv для запуска проекта для клиента, но получаю сообщение об ошибке ModuleNotFound для sklearn.

В моем Pipfile я добавил зависимость numpy

numpy = "==1.21.6"

Ошибка вылетает из следующей строки

np.load(PATH_TO_NPY_FILE, allow_pickle=True)

со следующей трассировкой стека:

development_1  |   File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.7/site-packages/numpy/lib/npyio.py", line 441, in load
development_1  |     pickle_kwargs=pickle_kwargs)
development_1  |   File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.7/site-packages/numpy/lib/format.py", line 748, in read_array
development_1  |     array = pickle.load(fp, **pickle_kwargs)
development_1  | ModuleNotFoundError: No module named 'sklearn'

Я нахожу это странным, потому что sklearn должен быть установлен как часть дерева зависимостей numpy, верно?

Тем не менее, я попробовал предложения, которые я нашел в других сообщениях, например, добавление следующей команды явно в мой Dockerfile

python -m pip install scikit-learn scipy matplotlib

Однако ошибка по-прежнему сохраняется.

Для полноты я предоставлю дополнительную информацию ниже, хотя ключевой вопрос остается, почему установка numpy не подразумевает наличия его подзависимостей.


Структура проекта

Проект является своеобразным мостом между SQS с одной стороны и логикой клиента с другой. Код, из которого возникает ошибка, исходит из подмодуля git, а Pipfile добавляется в репозиторий верхнего уровня. Подмодуль не содержит Pipfile. В папке submodules есть файл __init__.py, потому что он содержит функции, которые я хочу использовать в своем коде src. В дереве ниже мой код находится в main.py, а код выдачи ошибки — в submodules/module2/bar.py.

|- src/
|  |- main.py
|
|- submodules/
|  |- module1
|  |  |- foo.py
|  |  |- setup.py
|  |
|  |- module2
|  |  |- bar.py
|  |
|  |- __init__.py
|
|- .gitmodules
|- Pipfile
|- Dockerfile

Содержимое Dockerfile

Обратите внимание, что на данный момент это своего рода совокупность решений, которые я взял из другого поста по этому вопросу. Вот почему в настоящее время включены как pip install scikit-learn, так и apt-get install python3-sklearn. Обрежу позже, когда наконец решу эту проблему.

FROM python:3.7

WORKDIR code/

COPY Pipfile .
COPY submodules/ submodules/

RUN pip install pipenv && \
    pipenv install --deploy  && \
    python -m pip install scikit-learn scipy matplotlib && \
    apt-get update && \
    apt-get install -y locales ffmpeg libsm6 libxext6 libxrender-dev python3-sklearn && \
    sed -i -e 's/# nl_BE.UTF-8 UTF-8/nl_BE.UTF-8 UTF-8/' /etc/locale.gen && \
    dpkg-reconfigure --frontend=noninteractive locales

ENV LANG nl_BE.UTF-8
ENV LC_ALL nl_BE.UTF-8

COPY .env .
COPY src/ .
COPY data/ data

CMD [ "pipenv", "run", "python", "main.py" ]x

Содержимое пип-файла

[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]
python-dotenv = "*"
boto3 = "*"
pySqsListener = "*"
xpress = "==9.0.5"
module1 = {path = "./submodules/module1"}
pandas = "==1.3.4"
numpy = "==1.21.6"

[dev-packages]

[requires]
python_version = "3.7"
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нахожу это странным, потому что sklearn должен быть установлен как часть дерева зависимостей numpy, верно?

Нет, scikit-learn не зависит от numpy (наоборот).

Поскольку для загрузки этого файла рассола требуется sklearn, просто поместите scikit-learn в pipfile (и matplotlib, если вам это нужно); это зависимость вашего проекта.

Установка их за пределами pipenv-сгенерированной среды с этим python -m pip install scikit-learn scipy matplotlib, скорее всего, не будет иметь никакого эффекта (как и apt-installed python3-sklearn), поскольку виртуальные окружения спроектированы так, чтобы быть отделенными от окружающей среды.

Ах, тогда я, должно быть, ошибся насчет того, что зависит от чего. Я основывал свое предположение на трассировке стека, вызывающей ModuleNotFoundError из папки numpy. Также кажется, что вторая часть вашего ответа имеет смысл, и добавление ее в Pipfile действительно устраняет ошибку. Спасибо

gleerman 13.04.2023 11:01

Исключение фактически возникает внутри pickle.load() (которое вызывается numpy.load()), когда встроенный механизм десериализации Python пытается десериализовать что-то, что ссылается на sklearn. Но да, рад, что смог помочь!

AKX 13.04.2023 12:31

Другие вопросы по теме