很好地支持从多个文件中读取。但是,如果您的架构不同,那就有点棘手了。 Pyarrow 当前默认使用它在数据集中找到的第一个文件的模式。这是为了避免检查大型数据集中每个文件的架构的前期成本。
Arrow-C++ 有 the capability 覆盖它并扫描每个文件,但这还没有在 pyarrow 中公开。但是,如果您提前知道统一模式,则可以提供它,您将获得所需的行为。您将需要直接使用数据集模块来执行此操作,因为指定架构不是 pyarrow.parquet.read_table 的一部分(这是由 pandas.read_parquet 调用的)。
import pyarrow as pa
import pyarrow.dataset as ds
import pyarrow.parquet as pq
import pandas as pd
import tempfile
tab1 = pa.Table.from_pydict({'a': [1, 2, 3], 'b': ['a', 'b', 'c']})
tab2 = pa.Table.from_pydict({'b': ['a', 'b', 'c'], 'c': [True, False, True]})
unified_schema = pa.unify_schemas([tab1.schema, tab2.schema])
with tempfile.TemporaryDirectory() as dataset_dir:
pq.write_table(tab1, f'{dataset_dir}/one.parquet')
pq.write_table(tab2, f'{dataset_dir}/two.parquet')
print('Basic read of directory will use schema from first file')
print(pd.read_parquet(dataset_dir))
print()
print('You can specify the unified schema if you know it')
dataset = ds.dataset(dataset_dir, schema=unified_schema)
print(dataset.to_table().to_pandas())
print()
print('The columns option will limit which columns are returned from read_parquet')
print(pd.read_parquet(dataset_dir, columns=['b']))
print()
print('The columns option can be used when specifying a schema as well')
dataset = ds.dataset(dataset_dir, schema=unified_schema)
print(dataset.to_table(columns=['b', 'c']).to_pandas())
如果您不提前知道统一架构,您可以自己检查所有文件来创建它:
# You could also use glob here or whatever tool you want to
# get the list of files in your dataset
dataset = ds.dataset(dataset_dir)
schemas = [pq.read_schema(dataset_file) for dataset_file in dataset.files]
print(pa.unify_schemas(schemas))
由于这可能很昂贵(尤其是在使用远程文件系统时),您可能希望将统一架构保存在自己的文件中(保存一个 parquet 文件或 0 个批次的 Arrow IPC 文件通常就足够了)而不是重新计算它每次。