PyInstaller и Панды

У меня есть довольно простой модуль Python, который я пытаюсь скомпилировать в файл.exe Windows. В моем скрипте я использую библиотеки wxPython и Pandas. Сгенерированный.exe-файл PyInstaller работает / открывается только тогда, когда библиотека Pandas исключена из моего модуля.

Я получаю ту же проблему, использую ли я --onefile или же --onedir в PyInstaller. В Интернете я обнаружил, что "новая" версия PyInstaller (2.1) должна была позаботиться об этой ошибке. У кого-нибудь есть идеи, что делать?

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

10 ответов

Я столкнулся с той же проблемой. Я свел его к простому сценарию, как этот Hello.py:

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

Чтобы правильно импортировать панд во время выполнения, мне пришлось изменить 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

из командной строки и получил сообщение "привет мир", который я ожидал. Я до сих пор не совсем понимаю, почему это необходимо. У меня есть пользовательская сборка панд - которая подключена к библиотекам MKL - но мне не ясно, что это вызывает сбой запуска.

Это похоже на ответ здесь: Pyinstaller не делает правильный импорт pycripto... иногда

У меня была похожая проблема с pyinstaller версии 3.3. Решение было в том, что отсутствовал скрытый хук импорта, как описано здесь

Я создал новый файл в Pyinstaller/hooks/ под названием hook-pandas.py и поместил содержимое, как описано в этом коммите, и переустановил pyinstaller вручную через python setup.py install в каталоге Pyinstaller.

Проблема не повторялась, когда я создавал exe-файл из своего сценария pandas с помощью pyinstaller, используя параметр --onefile.

Так же, как другое решение, добавив --hidden-import=pandas._libs.tslibs.timedelta или какой-либо модуль отсутствует в pyinstaller Команда тоже работает.

Это может быть полезно, если вы не хотите прикасаться к источнику pyinstaller.

У меня была точно такая же проблема, и я нашел другое решение (на самом деле единственное, которое сработало для меня):

Я следил в значительной степени за этим: https://medium.com/@liron92/pyinstaller-with-pandas-problems-solutions-and-workflow-with-code-examples-c72973e1e23f

За исключением того факта, что я запускаю свою виртуальную среду на Anaconda.

Быстрое пошаговое решение

Прежде чем я начну: это шаги, которые я выполнил в моем конкретном случае, вы можете немного изменить их в зависимости от вашей ситуации.

1) Создайте и настройте свою виртуальную среду

Я использовал Anaconda для создания своего env:

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 Prompt:

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 = []и добавьте весь неявный импорт (включая панды). В моем случае я также использовал Tkinter, поэтому я указал:

hiddenimports=['pandas', 'tkinter']

4) Наконец запустите pyinstaller

В том же окне Anaconda Prompt (среда активирована в каталоге вашего проекта):

pyinstallermain.spec

И тогда все готово!

Отказ от ответственности

Я везде вижу людей, которые говорят вам, что вам следует использовать --onefileкогда вы компилируете проект Python с помощью Pyinstaller, я честно думаю, что вам не следует этого делать: это замедляет работу *.exe. Может быть, мне что-то не хватает, поэтому, пожалуйста, объясните мне, если вы используете это.

Технические характеристики

Windows 10
Anaconda 4.8.2
Python 3.7.6
Pandas 1.0.5

Для всех, кто хочет преобразовать скрипты Python с участием pandas в exe в 2021 году

Я много боролся с pyinstaller, но добился отличных результатов с Nuitka. Перки:

  • малый размер файла (500 КБ)
  • быстрое время сборки и выполнения (аналогично времени выполнения Python)
  • и самое главное: панды сразу поддерживают без виртуальных окружений!

Просто установите nuitka

pip install nuitka

и построить exe

nuitka hello.py

После этого вы даже можете использовать upx для дальнейшего сжатия!

upx hello.exe

В моем случае размер файла уменьшен до 1/3, всего ~150 КБ .exe размер файла для простого чтения скрипта pandas и сохранения файла excel.

См. Мое сообщение в блоге для получения дополнительной информации.

если кто-нибудь здесь использует python 3.10 :

вы, вероятно, столкнетесь с ошибкой «IndexError: индекс кортежа вне диапазона» .

починить это:

Я нашел решение этой проблемы. Это ошибка 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

Мое решение найдено в марте 2023 года:

ДОБАВИТЬ к .venvсписок пакетов

Фон:

      Environment:
    MacOS Ventura (13.2.1)
    Developed in PyCharm @022.3.2 (Professional Edition) 
    Using pipenv version 2023.2.18 (brew installation)
    pandas 1.5.3
    pyinstaller 5.9.0

Решение, которое я нашел, заключалось в том, чтобы УБЕДИТЬСЯ, что я установил пакет в список настроек/проекта/интерпретатора Python/пакетов Pycharm --- добавленоpyinstaller

И теперь все РАБОТАЕТ нормально.

Я решил ту же проблему, используя файл ловушек в каталоге проекта (согласно документу pyinstaller), hook-pandas.py

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

затем добавив одну строку в файл спецификации:

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

Я пытался включить hiddenimports=[..., 'pandas', ...] в файле спецификации как-то не получилось, как ожидалось.

Эта проблема была решена в pyinstaller 4.10.

С python version=3.8 и pyinstaller=3.6 нет необходимости настраивать pyinstaller или добавлять хуки pandas, hook-pandas.py уже существует в Lib\site-packages\PyInstaller\hooks, и все работает нормально.

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