在相同环境下使用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_datasetScanner类。

无处不在,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')

以上是在相同环境下使用CLI与可执行文件从parquet读取DataFrame时的不同行为的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>