PyInstaller и Pandas

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

Получавам същия проблем, независимо дали използвам --onefile или --onedir в PyInstaller. Открих онлайн, че "новата" версия на PyInstaller (2.1) трябваше да се погрижи за този бъг. Някой има ли идеи какво да правя?

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

person bsheehy    schedule 17.03.2015    source източник
comment
Публикацията ми беше изтрита от ChrisF♦, надявам се тази връзка да помогне на всеки, който търси подробен отговор на този въпрос Създаденият от Pyinstaller exe файл не може да зареди модел keras nn   -  person Santhosh Dhaipule Chandrakanth    schedule 18.07.2019


Отговори (7)


Сблъсках се със същия проблем. Сведох го до прост скрипт като този 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

от командния ред и получих съобщението „здравей свят“, което очаквах. Все още не разбирам напълно защо е необходимо това. Имам персонализирана компилация на pandas - която е свързана с MKL библиотеките - но не ми е ясно дали това причинява неуспешно изпълнение.

Това е подобно на отговора тук: Pyinstaller не импортира правилно pycripto... понякога

person physicistintheory    schedule 06.10.2015
comment
@ physicistintheory -- След като използвах вашето предложение, моята програма работи чудесно за мен с console=True, но не работи, когато console=False. Но когато кажа True, получавам черния команден прозорец в края заедно с търсения ми exe прозорец, който не е задължителен. Когато се опитам да изтрия черния прозорец, желаният ми прозорец също се затваря. Можете ли да ми предложите! - person ali; 12.12.2018
comment
какво е дърво в този контекст? - person Nebi M Aydin; 07.02.2020

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

Създадох нов файл под Pyinstaller/hooks/, наречен hook-pandas.py, и поставих съдържанието, както е описано в този комит тук и преинсталира pyinstaller ръчно чрез python setup.py install в директорията на Pyinstaller.

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

person John    schedule 26.11.2017
comment
Това работи за мен, въпреки че не трябваше да преинсталирам Pyinstaller. - person kaisquared; 05.03.2018
comment
Този отговор опростява всичко до куп командни редове: stackoverflow.com/a/48846546/4355695 - person Nikhil VJ; 24.04.2018

Точно като друго решение, добавянето на --hidden-import=pandas._libs.tslibs.timedelta или какъвто и да е модулът липсва към командата pyinstaller също работи.

Това може да е полезно, ако не искате да докосвате източника на pyinstaller.

person Alto.Clef    schedule 11.07.2018

Имах точно същия проблем и намерих друго решение (единственото, което всъщност работи за мен):

Проследих почти това: 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 Prompt:

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 (активирана среда, в директорията на вашия проект):

pyinstaller main.spec

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

Опровержение

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

спецификации

Windows 10
Anaconda 4.8.2
Python 3.7.6
Pandas 1.0.5
person Arthur    schedule 23.07.2020

Реших същия проблем, като използвах файл с кука в директорията на проекта (на документ на 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', ...] в спецификационния файл, но някак си това не се получи според очакванията.

person mikey    schedule 17.11.2018

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

person vpa    schedule 06.04.2020
comment
Не работи за мен, когато .exe беше създаден на Windows 7, но се опитах да го стартирам на Windows 10. Pyinstaller 3.6, Python 3.8.2 - person Charalamm; 26.05.2020
comment
Не ми работи с python 3.8.3 и pyinstaller 3.6 - person EBH; 03.06.2020

За всеки, който иска да конвертира скриптове на Python с включени pandas в exe през 2021 г

Затрудних се много с pyinstaller, но постигнах перфектни резултати с Нуитка. Бонус:

  • малък размер на файла (500kB)
  • бързо изграждане и време за изпълнение (подобно на времето за изпълнение на Python)
  • и най-доброто от всичко: pandas поддържат готови без виртуални envs!

Просто инсталирайте nuitka

pip install nuitka

и изградете exe

nuitka hello.py

Можете дори да използвате upx след това, за да компресирате допълнително!

upx hello.exe

В моя случай размерът на файла беше намален до 1/3, само ~150kB .exe размер на файла за обикновен скрипт на pandas, който чете и записва excel-файл.

Вижте моята публикация в блог за повече подробности.

person do-me    schedule 25.06.2021