在相同环境下使用CLI与可执行文件从parquet读取DataFrame时的不同行为
请考虑以下程序作为最小可重现示例 -MRE:
import pandas as pd
import pyarrow
from pyarrow import parquet
def foo():
print(pyarrow.__file__)
print('version:',pyarrow.cpp_version)
print('-----------------------------------------------------')
df = pd.DataFrame({'A': [1,2,3], 'B':['dummy']*3})
print('Orignal DataFrame:n', df)
print('-----------------------------------------------------')
_table = pyarrow.Table.from_pandas(df)
parquet.write_table(_table, 'foo')
_table = parquet.read_table('foo', columns=[]) #passing empty list to columns arg
df = _table.to_pandas()
print('After reading from file with columns=[]:n', df)
print('-----------------------------------------------------')
print('Not passing [] to columns parameter')
_table = parquet.read_table('foo') #Not passing any list
df = _table.to_pandas()
print(df)
print('-----------------------------------------------------')
x = input('press any key to exit: ')
if __name__=='__main__':
foo()
当我从控制台/IDE 运行它时,它会读取以下所有数据columns=[]:
(env) D:foo>python foo.py
D:fooenvlibsite-packagespyarrow__init__.py
version: 3.0.0
-----------------------------------------------------
Orignal DataFrame:
A B
0 1 dummy
1 2 dummy
2 3 dummy
-----------------------------------------------------
After reading from file with columns=[]:
A B
0 1 dummy
1 2 dummy
2 3 dummy
-----------------------------------------------------
Not passing [] to columns parameter
A B
0 1 dummy
1 2 dummy
2 3 dummy
-----------------------------------------------------
press any key to exit:
但是当我从使用 Pyinstaller 创建的可执行文件运行它时,它没有读取以下数据columns=[]:
E:foodistfoopyarrow__init__.pyc
version: 3.0.0
-----------------------------------------------------
Orignal DataFrame:
A B
0 1 dummy
1 2 dummy
2 3 dummy
-----------------------------------------------------
After reading from file with columns=[]:
Empty DataFrame
Columns: []
Index: [0, 1, 2]
-----------------------------------------------------
Not passing [] to columns parameter
A B
0 1 dummy
1 2 dummy
2 3 dummy
-----------------------------------------------------
press any key to exit:
正如您所看到的,传递columns=[]在可执行文件中给出了空数据帧,但是在直接运行 python 文件时这种行为不存在,而且我不确定为什么在同一环境中对同一代码有这两种不同的行为。
综观文档字符串parquet.read_table中在GitHub的源代码:
columns: list
如果不是 None,则只会从文件中读取这些列。列名可以是嵌套字段的前缀,例如“a”将选择“a.b”、“a.c”和“ade”。
该read_table进一步呼叫dataset.read的呼叫_dataset.to_table返回调用self.scanner,然后返回调用静态方法from_dataset的Scanner类。
无处不在,None一直被用作columns参数的默认值,如果None和[]在python中直接转换为布尔值,两者确实会是False,但如果[]是检查None,那么会是False,但没有提到它是否应该获取所有列对于columns=[]因为它的计算结果是False布尔值,或因为该列表是空的应该它在所有阅读没有列。
但是,为什么从命令行/IDE 运行它时的行为与从使用 Pyinstaller 为相同版本的 Pyarrow 创建的可执行文件运行它时的行为不同?
我所在的环境:
- Python 版本:3.7.6
- Pyinstaller 版本:4.2
- Pyarrow 版本:3.0.0
- Windows 10 64 位操作系统
如果您想尝试一下,这里是您参考的规范文件(您需要更改pathex参数):
foo.spec
# -*- mode: python ; coding: utf-8 -*-
import sys ; sys.setrecursionlimit(sys.getrecursionlimit() * 5)
block_cipher = None
a = Analysis(['foo.py'],
pathex=['D:foo'],
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='foo',
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,
upx_exclude=[],
name='foo')
THE END
二维码