【问题标题】:How do you make a PyArrow Dataset out of an IO stream?如何从 IO 流中创建 PyArrow 数据集?
【发布时间】:2022-01-25 10:49:03
【问题描述】:

我有一个 python 程序作为文件读取器读取 parquet 文件,并试图用它来构造一个 pyarrow 数据集。我可以使用以下方法将文件读取器读入 pyarrow 表:

    import pyarrow.parquet as pq

    table = pq.read_table(file_reader)

但是,将文件读取器直接传递给数据集初始化程序会出错。这是有道理的,因为 pyarrow 文档显示 ds.dataset 函数不接受文件读取器作为数据源:

    import pyarrow.dataset as ds

    dataset = ds.dataset(file_reader) # TypeError: Expected a path-like, list of path-likes or a list of 
                                       # Datasets instead of the given type

我正在尝试的当前解决方法是将流作为表格读取,然后将表格作为数据集读取:

    import pyarrow.parquet as pq
    import pyarrow.dataset as ds

    table = pq.read_table(input_stream)
    dataset = ds.dataset(table)

但是,我不确定这是否是数据集的有效解决方法,因为数据集可能期望传递的表由基础文件支持,但事实并非如此。

【问题讨论】:

    标签: pyarrow


    【解决方案1】:

    我不完全确定您所说的“文件阅读器”是什么意思。 Arrow 有一个 C++ 类 parquet::arrow::FileReader,但我认为 pyarrow 没有记录绑定,尽管它在内部用于像 pyarrow.parquet.ParquetFile.iter_batches 这样的函数。

    无论哪种方式,答案可能是您无法从文件阅读器创建数据集,但您也可能不需要。

    数据集通常用于创建扫描仪,然后可以直接用于迭代处理(可能过滤或投影数据)或作为pyarrow.dataset.write_dataset 之类的输入。

    import pyarrow as pa
    import pyarrow.parquet as pq
    import pyarrow.dataset as ds
    
    tab = pa.Table.from_pydict({'a': [1, 2, 3], 'b': ['x', 'y', 'z']})
    pq.write_table(tab, '/tmp/foo.parquet')
    
    parquet_file = pq.ParquetFile('/tmp/foo.parquet')
    schema = parquet_file.schema_arrow
    itr = parquet_file.iter_batches()
    
    scanner = ds.Scanner.from_batches(itr, schema=schema, columns=['a'], filter=ds.field('b') == 'y')
    print(scanner.to_table())
    

    这里缺少的主要内容是您不会有任何过滤器下推。显然我们不能做任何基于分区的过滤,因为只有一个文件,但我们也不能使用 parquet 的基于统计的行组过滤。

    您还需要确保在创建文件时只询问您需要的列(例如,由扫描仪的投影和过滤器选择的列)。否则,它将仅将这些列加载到内存中,以便扫描程序稍后删除它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-10
      • 1970-01-01
      • 2016-09-27
      • 2020-05-30
      • 2018-11-11
      • 1970-01-01
      • 2020-04-25
      • 1970-01-01
      相关资源
      最近更新 更多