Pyinstaller;ModuleNotFoundError:找不到名为'sklearn.utils._cython_blas'的模块

11

我有一个Python项目的导入列表:

import pandas as pd
import time
import sqlalchemy
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
import numpy as np
from sqlalchemy import Column, String, Float, Integer, SmallInteger, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

以及这个用于分发项目的规范文件:

import sys
sys.setrecursionlimit(5000)

block_cipher = None


a = Analysis(['DataManager.py'],
             pathex=['E:\\ForexPredictor'],
             binaries=[],
             datas=[],
             hiddenimports=['cython','pymysql','pandas._libs.tslibs.timedeltas','sklearn.neighbors.typedefs','sklearn.utils.typedefs'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          [],
          exclude_binaries=True,
          name='DataManager',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          console=True )
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='DataManager')

我使用这个命令来制作项目的可执行文件:

pyinstaller Datamanager.spec

但是当我运行exe文件时,它会出现这个错误:

ModuleNotFoundError: No module named 'sklearn.utils._cython_blas'

隐藏导入的部分还应该添加哪些内容?


对于那些没有安装pyinstaller的人,只需运行pip install sklearn.utils并重新启动内核。 - AJ AJ
6个回答

28
PyInstaller使用hook机制来处理每个Python模块,但有时会漏掉一些内部包,因此您需要手动提供它们。您可以使用--hidden-import来添加sklearn缺少的模块。
pyinstaller -F --hidden-import="sklearn.utils._cython_blas" --hidden-import="sklearn.neighbors.typedefs" --hidden-import="sklearn.neighbors.quad_tree" --hidden-import="sklearn.tree._utils" Datamanager.py

7
这个方法可行,但每次构建只能发现一个缺失的软件包,然后我必须使用它来获取下一个缺失的软件包。难道没有一种一次性知道所有缺失软件包的方法吗? - astackoverflowuser
@Eren 这是一个很好的问题!我希望有人能帮助解决。 - Baggio

5

我没有尝试过,但我认为你可以通过添加以下内容来解决这个问题: --collect-submodules "sklearn"

我使用的是"Auto py to exe",它在内部使用pyinstaller并通过修改该参数来解决了这个问题。

如果你也使用"Auto py to exe",那么有两种方法可以解决这个问题。

  1. (这个方法解释了问题所在) 首先运行安装程序,不选择"one file"选项(选择一个目录)。 一旦进程完成,打开包含文件夹。在那里,你会发现sklearn文件夹,并且它没有被pyinstaller完全复制。因此,解决问题的方法是用"C:\PythonXY\Lib\site-packages"中具有相同名称"sklearn"的文件夹替换此文件夹。之后,exe文件将无问题地运行。

  2. (我更喜欢这个方法) 如果你也想使用一个文件将所有内容收集到exe文件中,你就不能手动替换sklearn文件夹。在这种情况下,你必须在"高级>要捆绑什么,在哪里搜索>收集子模块"中写入"sklearn"(不带引号)。


3
--collect-submodules "sklearn" 对我很有帮助。在我看来,这是一个比被接受的答案更干净的命令。 - Max Peglar-Willis

5

添加

import sklearn.utils._cython_blas

也许

import sklearn.neighbors.typedefs
import sklearn.neighbors.quad_tree
import sklearn.tree
import sklearn.tree._utils

将此代码添加到你的程序中。


1
当您导入sklearn.tree时,同时导入import sklearn.tree._utils是多余的。 - borievka
这是最好的方式! - Sajjad Aemmi

2
执行以下代码后,我的代码能够正常工作:

pyinstaller --hidden-import="sklearn.utils._cython_blas" --hidden-import="sklearn.neighbors.typedefs" --hidden-import="sklearn.neighbors.quad_tree" --hidden-import="sklearn.tree._utils" --hidden-import="sklearn.neighbors._typedefs" --hidden-import="sklearn.utils._weight_vector" --hidden-import="sklearn.neighbors._quad_tree" namepythonfile.py

尝试将所有模块添加到隐藏导入代码中才能成功。

我不知道如何格式化代码,请提供建议。 - M.Nuramzan Iftari

1

是的,我已经阅读了它。我认为问题在于隐藏导入部分。我不知道还应该添加哪些内容到这个部分。 - amin mohammadi

1

我在使用auto_py_to_ex时遇到了同样的问题...通过将程序数据/anaconda3/env/sitepackages中的sklearn文件夹复制到主文件夹中解决了这个问题


你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接