读取大量镶木地板文件:read_parquet vs from_delayed

Reading large number of parquet files: read_parquet vs from_delayed

我正在将大量(100s 到 1000s)的镶木地板文件读入单个 dask 数据帧(单台机器,所有本地)。我意识到

files = ['file1.parq', 'file2.parq', ...]
ddf = dd.read_parquet(files, engine='fastparquet')
ddf.groupby(['col_A', 'col_B']).value.sum().compute()

效率低很多
from dask import delayed
from fastparquet import ParquetFile

@delayed
def load_chunk(pth):
    return ParquetFile(pth).to_pandas()

ddf = dd.from_delayed([load_chunk(f) for f in files])
ddf.groupby(['col_A', 'col_B']).value.sum().compute()

对于我的特定应用程序,第二种方法 (from_delayed) 需要 6 秒才能完成,第一种方法需要 39 秒。在 dd.read_parquet 的情况下,在工作人员开始做某事之前似乎有很多开销,并且有相当多的 transfer-... 操作分散在任务流图中。我想了解这里发生了什么。 read_parquet 方法慢得多的原因可能是什么?它与仅读取文件并将它们放入块中有什么不同?

您正在体验客户端试图建立数据列的min/max 统计信息,从而为数据帧建立良好的索引。索引对于防止读取特定作业不需要的数据文件非常有用。

在很多情况下,这是一个好主意,因为文件中的数据量很大而文件总数很少。在其他情况下,相同的信息可能包含在一个特殊的“_metadata”文件中,这样就不需要先从所有文件中读取。

要防止扫描文件的页脚,您应该调用

dd.read_parquet(..,. gather_statistics=False)

这应该是下一版本 dask 的默认值。