Dask 从S3打开大文件

Dask 从S3打开大文件,dask,Dask,当我试图从S3打开一个大文件时,我得到了内存错误 import dask.dataframe as dd df = dd.read_csv('s3://xxxx/test_0001_part_03.gz', storage_options={'anon': True}, compression='gzip', error_bad_lines=False) df.head() exception: MemoryError 如何直接从S3打开大型压缩文件?简短回答 您不能对单个大型gzip文件

当我试图从S3打开一个大文件时,我得到了内存错误

import dask.dataframe as dd
df = dd.read_csv('s3://xxxx/test_0001_part_03.gz', storage_options={'anon': True}, compression='gzip', error_bad_lines=False) 

df.head()
exception: MemoryError
如何直接从S3打开大型压缩文件?

简短回答 您不能对单个大型gzip文件执行此操作,因为gzip压缩不允许随机访问

长话短说 通常,对于大文件,Dask将提取固定大小的数据块(如128MB),并独立处理它们。然而,像GZip这样的一些压缩格式不允许像这样简单的分块访问。如果有许多小文件,仍然可以将gzip数据与Dask一起使用,但每个文件都将被视为一个块。如果这些文件很大,那么您将遇到内存错误,正如您所经历的那样


您可以使用dask.bag,它通常非常适合通过流式传输结果。但是,您将无法获得Pandas语义,也无法在单个文件中获得任何并行性。

您可能已经想到了几个简单的解决方案:

  • 将文件解压缩后存储在S3上;可能具有更大的文件大小和相应较慢的传输速度
  • 下载到本地解压缩文件;当然,您需要有足够的本地存储
后者可以通过以下方式实现

import s3fs, gzip
s3 = s3fs.S3FileSystem(anon=True)
with s3.open('s3://xxxx/test_0001_part_03.gz', 'rb') as f1:
    with open('local_file', 'wb') as f2:
        f3 = gzip.GzipFile(fileobj=f1, mode='rb')
        out = True
        while out:
            out = f3.read(128*2**10)
            f2.write(out)

注意:我们没有为S3明确提供多线程文件下载器,尽管可以将其做成这样,但您的带宽很可能会被一个线程占用。