pandas 如何使用 pyinstaller 创建最小大小的可执行文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48629486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 05:08:20  来源:igfitidea点击:

How can I create the minimum size executable with pyinstaller?

pythonpandasanacondavirtualenvpyinstaller

提问by esperluette

I am on Windows 10, I have anaconda installed but I want to create an executable independently in a new, clean minimal environment using python 3.5. So I did some tests:

我在 Windows 10 上,我安装了 anaconda,但我想使用 python 3.5 在一个新的、干净的最小环境中独立创建一个可执行文件。所以我做了一些测试:

TEST1: I created a python script test1.py in the folder testenv with only:

TEST1:我在文件夹 testenv 中创建了一个 python 脚本 test1.py,只有:

print('Hello World')

Then I created the environment, installed pyinstaller and created the executable

然后我创建了环境,安装了pyinstaller并创建了可执行文件

D:\testenv> python -m venv venv_test
...
D:\testenv\venv_test\Scripts>activate.bat
...
(venv_test) D:\testenv>pip install pyinstaller
(venv_test) D:\testenv>pyinstaller --clean -F test1.py

And it creates my test1.exe of about 6 Mb

它创建了我的 test1.exe 大约 6 Mb

TEST 2: I modified test1.py as follows:

测试 2:我修改 test1.py 如下:

import pandas as pd
print('Hello World')  

I installed pandas in the environment and created the new executable:

我在环境中安装了 pandas 并创建了新的可执行文件:

(venv_test) D:\testenv>pip install pandas
(venv_test) D:\testenv>pyinstaller --clean -F test1.py

Ant it creates my test1.exe which is now of 230 Mb!!!

Ant 它创建了我的 test1.exe,它现在是230 Mb!!!

if I run the command

如果我运行命令

(venv_test) D:\testenv>python -V
Python 3.5.2 :: Anaconda custom (64-bit)

when I am running pyinstaller I get some messages I do not understand, for example:

当我运行 pyinstaller 时,我收到一些我不明白的消息,例如:

INFO: site: retargeting to fake-dir 'c:\users\username\appdata\local\continuum\anaconda3\lib\site-packages\PyInstaller\fake-modules'

Also I am getting messages about matplotlib and other modules that have nothing to do with my code, for example:

此外,我收到有关 matplotlib 和其他与我的代码无关的模块的消息,例如:

INFO:   Matplotlib backend "pdf": added
INFO:   Matplotlib backend "pgf": added
INFO:   Matplotlib backend "ps": added
INFO:   Matplotlib backend "svg": added

I know there are some related questions: Reducing size of pyinstaller exe, size of executable using pyinstaller and numpybut I could not solve the problem and I am afraid I am doing something wrong with respect to anaconda.

我知道有一些相关的问题: 减少pyinstaller exe文件的大小可执行使用pyinstaller和numpy的大小,但我没能解决问题,恐怕我做错了什么关于蟒蛇。

So my questions are: what am I doing wrong? can I reduce the size of my executable?

所以我的问题是:我做错了什么?我可以减少可执行文件的大小吗?

采纳答案by Dragomeow

The problem is that you should not be using a virtual environment and especially not anaconda. Please download default python 32 bit and use only necessary modules. Then follow the steps provided in the links, this should definitely fix it.

问题是您不应该使用虚拟环境,尤其是 anaconda。请下载默认的 python 32 位并仅使用必要的模块。然后按照链接中提供的步骤进行操作,这肯定会解决它。

Although you created a virtual env, are you sure your spec file is not linking to old Anaconda entries?

尽管您创建了一个虚拟环境,但您确定您的规范文件没有链接到旧的 Anaconda 条目吗?

If all this fails, then submit a bug as this is very strange.

如果这一切都失败了,那么提交一个错误,因为这很奇怪。

回答by esperluette

I accepted the answer above but I post here what I did step by step for complete beginners like me who easily get lost.

我接受了上面的答案,但我在这里发布了我为像我这样容易迷路的完全初学者一步一步做的事情。

Before I begin I post my complete test1.py example script with all the modules I actually need. My apologies if it is a bit more complex than the original question but maybe this can help someone.

在开始之前,我发布了包含我实际需要的所有模块的完整 test1.py 示例脚本。如果它比原始问题更复杂一点,我深表歉意,但也许这可以帮助某人。

test1.py looks like this:

test1.py 看起来像这样:

import matplotlib 
matplotlib.use('Agg') 
import matplotlib.pyplot as plt
import matplotlib.image as image
import numpy as np
import os.path
import pandas as pd
import re   

from matplotlib.ticker import AutoMinorLocator 
from netCDF4 import Dataset
from time import time
from scipy.spatial import distance
from simpledbf import Dbf5
from sys import argv

print('Hello World')

I added matplotlib.use('Agg') (as my actual code is creating figures) Generating a PNG with matplotlib when DISPLAY is undefined

我添加了 matplotlib.use('Agg') (因为我的实际代码正在创建数字) 当 DISPLAY 未定义时,用 matplotlib 生成一个 PNG

1) Install a new version of python independently from anaconda.

1)独立于anaconda安装新版本的python。

downloaded python from: https://www.python.org/downloads/installed selecting 'add python to path' and deselecting install launcher for all users (I don't have admin rights) check that I am using the same version from CMD, just writing pythonI get: Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.

从以下位置下载 python:https: //www.python.org/downloads/安装 选择“将 python 添加到路径”并为所有用户取消选择安装启动器(我没有管理员权限)检查我是否使用了来自 CMD 的相同版本,只是写python我得到:Python 3.6.4 (v3.6.4:d48eceb, 2017 年 12 月 19 日,06:04:45) [MSC v.1900 32 位(英特尔)] on win32 键入“帮助”、“版权”、“学分”或“许可证”以获取更多信息。

2) Create and activate the environment, from CMD

2)从CMD创建并激活环境

D:\> mkdir py36envtest
...
D:\py36envtest>python -m venv venv_py36
...
D:\py36envtest\venv_py36\Scripts>activate.bat

3) Install in the environment all the modules needed in the script

3)在环境中安装脚本中需要的所有模块

Making sure they are compatible to the python version with the command: (from Matplotlib not recognized as a module when importing in Python)

使用命令确保它们与 python 版本兼容:(从Matplotlib 在 Python 中导入时不被识别为模块

(venv_py36) D:\py36envtest> python -m pip install nameofmodule

NB: in my case I also had to add the option --proxy https://00.000.000.00:0000

注意:就我而言,我还必须添加选项 --proxy https://00.000.000.00:0000

for the example I used development version of py installer:

例如,我使用了 py 安装程序的开发版本:

(venv_py36) D:\py36envtest> python -m pip install https://github.com/pyinstaller/pyinstaller/archive/develop.tar.gz

and the modules: pandas, matplolib, simpledbf, scipy, netCDF4. At the end my environment looks like this.

和模块:pandas、matplolib、simpledbf、scipy、netCDF4。最后我的环境看起来像这样。

(venv_py36) D:\py36envtest> pip freeze
altgraph==0.15
cycler==0.10.0
future==0.16.0
macholib==1.9
matplotlib==2.1.2
netCDF4==1.3.1
numpy==1.14.0
pandas==0.22.0
pefile==2017.11.5
PyInstaller==3.4.dev0+5f9190544
pyparsing==2.2.0
pypiwin32==220
python-dateutil==2.6.1
pytz==2017.3
scipy==1.0.0
simpledbf==0.2.6
six==1.11.0
style==1.1.0
update==0.0.1

4) Create/modify the .spec file (when you run pyinstaller it creates a .spec file, you can rename).

4) 创建/修改 .spec 文件(当你运行 pyinstaller 时它会创建一个 .spec 文件,你可以重命名)。

Initially I got a lot of ImportError: DLL load failed (especially for scipy) and missing module error which I solved thanks to these posts:
What is the recommended way to persist (pickle) custom sklearn pipelines?
and the comment to this answer: Pyinstaller with scipy.signal ImportError: DLL load failed

最初,我收到了很多 ImportError: DLL load failed (特别是对于 scipy) 和缺少模块错误,这要归功于这些帖子,我解决了这些错误:
持久化(pickle)自定义 sklearn 管道的推荐方法是什么?
以及对此答案的评论: Pyinstaller with scipy.signal ImportError: DLL load failed

My inputtest1.spec finally looks like this:

我的 inputtest1.spec 最终看起来像这样:

# -*- mode: python -*-
options = [ ('v', None, 'OPTION')]
block_cipher = None


a = Analysis(['test1.py'],
             pathex=['D:\py36envtest', 'D:\py36envtest\venv_py36\Lib\site-packages\scipy\extra-dll' ],
             binaries=[],
             datas=[],
             hiddenimports=['scipy._lib.messagestream',
                            'pandas._libs.tslibs.timedeltas'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='test1',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )

5) Finally make the executable with the command

5)最后用命令制作可执行文件

(venv_py36) D:\py36envtest>pyinstaller -F --clean inputtest1.spec

my test1.exe is 47.6 Mb, the .exe of the same script created from an anaconda virtual environment is 229 Mb.

我的 test1.exe 是 47.6 Mb,从 anaconda 虚拟环境创建的相同脚本的 .exe 是 229 Mb。

I am happy (and if there are more suggestions they are welcome)

我很高兴(如果有更多建议,欢迎提出)