【问题标题】:PyInstaller and PandasPyInstaller 和 Pandas
【发布时间】:2015-05-20 11:39:20
【问题描述】:

我有一个相当简单的 Python 模块,我正在尝试将其编译成 Windows .exe 文件。在我的脚本中,我使用的是 wxPython 和 Pandas 库。当 Pandas 库从我的模块中排除时,生成的 PyInstaller .exe 文件工作/打开。

无论我在 PyInstaller 中使用 --onefile 还是 --onedir,我都会遇到同样的问题。我在网上发现 PyInstaller (2.1) 的“新”版本应该已经解决了这个错误。有没有人知道该怎么做?

PyInstaller: version 2.1
pandas: version 0.15.2
Python: version 2.7

【问题讨论】:

标签: python pandas pyinstaller


【解决方案1】:

我遇到了同样的问题。我把它归结为一个简单的脚本,比如 Hello.py:

import pandas
print "hello world, pandas was imported successfully!"

为了让 pandas 在运行时正确导入,我必须将 Hello.spec 修改为以下内容:

# -*- mode: python -*-

block_cipher = None

def get_pandas_path():
    import pandas
    pandas_path = pandas.__path__[0]
    return pandas_path

a = Analysis(['Hello.py'],
         pathex=['C:\\ScriptsThatRequirePandas'],
         binaries=None,
         datas=None,
         hiddenimports=[],
         hookspath=None,
         runtime_hooks=None,
         excludes=None,
         win_no_prefer_redirects=None,
         win_private_assemblies=None,
         cipher=block_cipher)

dict_tree = Tree(get_pandas_path(), prefix='pandas', excludes=["*.pyc"])
a.datas += dict_tree
a.binaries = filter(lambda x: 'pandas' not in x[0], a.binaries)

pyz = PYZ(a.pure, a.zipped_data,
         cipher=block_cipher)
exe = EXE(pyz,
      a.scripts,
      exclude_binaries=True,
      name='Hello',
      debug=False,
      strip=None,
      upx=True,
      console=True )
scoll = COLLECT(exe,
           a.binaries,
           a.zipfiles,
           a.datas,
           strip=None,
           upx=True,
           name='Hello')

然后我跑了:

$pyinstaller Hello.spec --onefile

从命令提示符中得到了我期望的“hello world”消息。我仍然不完全理解为什么这是必要的。我有一个自定义构建的 pandas - 它与 MKL 库挂钩 - 但我不清楚这是否会导致运行失败。

这类似于这里的答案:Pyinstaller not correclty importing pycripto... sometimes

【讨论】:

  • @ physicistintheory -- 使用您的建议后,我的程序在 console=True 时效果很好,但在 console=False 时它不起作用。但是,当我说 True 时,我会在最后看到黑色命令窗口以及我想要的 exe 窗口,这不是必需的。当我尝试删除黑色窗口时,我想要的窗口也会关闭。你能推荐我吗!
  • 在这种情况下什么是树?
【解决方案2】:

我在 pyinstaller 3.3 版中遇到了类似的问题。解决方案是缺少一个 hiddenimport 挂钩,如here 所述

我在 Pyinstaller/hooks/ 下创建了一个名为 hook-pandas.py 的新文件,并将此提交中所述的内容 here 并通过 python setup.py install 在 Pyinstaller 目录中手动重新安装了 pyinstaller。

当我使用 --onefile 选项从我的 pandas 脚本创建 exe 时,该问题没有再次出现。

【讨论】:

【解决方案3】:

就像另一种解决方案一样,将--hidden-import=pandas._libs.tslibs.timedelta 或任何模块缺少的模块添加到pyinstaller 命令也可以。

如果您不想接触 pyinstaller 的源代码,这可能会有所帮助。

【讨论】:

    【解决方案4】:

    我遇到了完全相同的问题,但我找到了另一种解决方案(实际上唯一对我有用的解决方案):

    我非常关注这个:https://medium.com/@liron92/pyinstaller-with-pandas-problems-solutions-and-workflow-with-code-examples-c72973e1e23f

    除了我在 Anaconda 上运行我的虚拟环境。

    快速分步解决方案

    在开始之前:这些是我针对特定案例所遵循的步骤,您可能需要根据自己的情况进行一些调整。

    1) 创建和配置您的虚拟环境

    我使用 Anaconda 来创建我的环境:

    conda create --name myenv
    

    然后我安装了我需要的所有模块:

    conda install -n myenv pandas
    conda install -n myenv -c conda-forge python-docx
    etc.
    

    2) 激活您的环境并切换到项目路径

    在 Anaconda 提示符下:

    conda activate myenv
    cd path/to/your/project/folder
    

    3) 创建和修改您的 *.spec 文件

    仍然在同一个 Anaconda 提示窗口:

    pyi-makespec project.py
    

    然后打开你的 project.spec 文件,它看起来像这样:

    # -*- mode: python ; coding: utf-8 -*-
    
    block_cipher = None
    
    
    a = Analysis(['project.py'],
                 pathex=['path/to/your/project/folder'],
                 binaries=[],
                 datas=[],
                 hiddenimports=[],
                 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='main',
              debug=False,
              bootloader_ignore_signals=False,
              strip=False,
              upx=True,
              console=False )
    coll = COLLECT(exe,
                   a.binaries,
                   a.zipfiles,
                   a.datas,
                   strip=False,
                   upx=True,
                   upx_exclude=[],
                   name='main')
    

    您只需修改 hiddenimports = [] 并添加所有隐式导入(包括 pandas)。 就我而言,我也在使用 Tkinter,所以我指定了:

    hiddenimports=['pandas', 'tkinter']
    

    4) 最后运行 pyinstaller

    在同一个 Anaconda Prompt 窗口(环境已激活,在您的项目目录中):

    pyinstaller main.spec
    

    然后你就完成了!

    免责声明

    我看到到处有人告诉你在使用 Pyinstaller 编译 Python 项目时应该使用 --onefile,老实说,我认为你不应该这样做:它会使 *.exe 变慢。也许我错过了一些东西,所以如果你使用它,请向我解释一下。

    规格

    Windows 10
    Anaconda 4.8.2
    Python 3.7.6
    Pandas 1.0.5
    

    【讨论】:

      【解决方案5】:

      如果这里有人使用 python 3.10

      你可能会遇到“IndexError: tuple index out of range”错误。

      修复它:

      我找到了解决这个问题的方法。 这是一个 python 3.10 的错误,在应用修复后,与 pyinstaller 相关的所有内容都开始正常工作。

      " 所以基本上你必须去文件夹“Python310\Lib”并编辑文件“dis.py”。 在“dis.py”文件中,你必须找到这个“def _unpack_opargs”并在 else 语句中写一个新行:“extended_arg = 0”。

      我做了类似的事情:

          else:
              arg = None
              extended_arg = 0 
          yield (i, op, arg)
      

      现在一切正常。 " https://github.com/pyinstaller/pyinstaller/issues/6301#issuecomment-974927257

      【讨论】:

      • 这对我有用,谢谢!
      【解决方案6】:

      我通过使用项目目录中的挂钩文件(每个 pyinstaller 文档)hook-pandas.py 解决了同样的问题

      hiddenimports = [
          'pandas._libs.tslibs.timedeltas',
          'pandas._libs.tslibs.nattype',
          'pandas._libs.tslibs.np_datetime',
          'pandas._libs.skiplist',
      ]
      

      然后在spec文件中添加一行:

      ...
      a = Analysis([...
      hookspath=['.'],
      ...],
      ...
      

      我试图在规范文件中包含hiddenimports=[..., 'pandas', ...],但不知何故没有按预期工作。

      【讨论】:

        【解决方案7】:

        使用 python version=3.8 和 pyinstaller=3.6,无需自定义 pyinstaller 或添加 pandas hook,hook-pandas.py 已经存在于 Lib\site-packages\PyInstaller\hooks 中,一切正常。

        【讨论】:

        • 在 Windows 7 上创建 .exe 时对我不起作用,但我尝试在 Windows 10 上运行它。Pyinstaller 3.6,Python 3.8.2
        • 不要为我使用 python 3.8.3 和 pyinstaller 3.6
        【解决方案8】:

        对于希望在 2021 年将涉及 pandas 的 Python 脚本转换为 exe 的任何人

        我在 pyinstaller 上挣扎了很多,但在 Nuitka 上得到了完美的结果。福利:

        • 小文件大小 (500kB)
        • 快速构建和执行时间(类似于 Python 执行时间)
        • 最重要的是:pandas 支持开箱即用,无需虚拟环境!

        只需安装 nuitka

        pip install nuitka

        并构建 exe

        nuitka hello.py

        你甚至可以在之后使用 upx 进一步压缩!

        upx hello.exe

        在我的例子中,文件大小减少到 1/3,只有 ~150kB .exe 文件大小,用于读取和保存 excel 文件的简单 pandas 脚本。

        更多详情请查看我的blog post

        【讨论】:

          猜你喜欢
          • 2016-01-05
          • 1970-01-01
          • 2018-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-10-21
          • 2013-09-01
          • 2015-12-09
          相关资源
          最近更新 更多