1

我正在将大型文本文件(VCF)中的数据读取到 zarr 数组中。代码的整体流程是

with zarr.LMDBStore(...) as store:
    array = zarr.create(..., chunks=(1000,1000), store=store, ...)
    for line_num, line in enumerate(text_file):
        array[line_num, :] = process_data(line)

我想知道 - zarr 何时压缩修改后的数组块并将它们推送到底层存储(在本例中为 LMDB)?每次更新块(即每一行)时都会这样做吗?或者它是否等到一个块被填充/从内存中删除后再这样做?假设我需要在 for 循环中分别处理每一行(由于数据和处理的性质,这里没有有效的数组操作可供使用),关于我如何馈送,我应该在这里做任何优化吗数据导入Zarr?

我只是不希望 Zarr 在每一行对每个修改的块运行压缩,因为每个块在完成并准备保存到磁盘之前将被修改 1000 次。

谢谢!

4

2 回答 2

2

每次执行此行时:

         array[line_num, :] = process_data(line)

...zarr 将 (1) 找出哪些块与您要写入的数组区域重叠,(2) 从存储中检索这些块,(3) 解压缩块,(4) 修改数据,(5) 压缩修改后的块,(6)将修改后的压缩块写入存储。

无论您使用什么类型的底层存储,都会发生这种情况。

如果您创建了一个包含超过一行高的块的数组,那么这可能效率低下,导致每个块被读取、解压缩、更新、压缩和写入多次。

更好的策略是将输入文件解析为 N 行块,其中 N 等于输出数组的每个块中的行数,以便每个块只压缩和写入一次。

如果 VCF 是指 Variant Call Format 文件,您可能需要查看 scikit-allel 中的vcf_to_zarr函数实现。

于 2020-05-11T11:38:13.683 回答
0

我相信 LMDB 存储(据我所知)每次分配时都会写入/压缩。

您可以在内存中的 Zarr 中聚合您的行,然后为每个块分配。

数据集可能有一个“批处理”选项,但据我所知尚未实现。

于 2020-05-10T21:26:38.890 回答