我在 s3
中有大量相对较小的文件。我需要读取每个文件,进行一些处理,然后将它们写回 Google Cloud Storage。每个文件都足够小以适合内存。保留每个文件的名称和内容很重要。
用于跨多个内核/线程扩展这项工作的最佳 dask
抽象是什么?
我尝试使用 dask.bag
处理文件并成功处理小批量文件,但在尝试处理大量文件时遇到内存问题。
我在读取文件时使用了 include_path
但无法找到一种方法让 to_textfiles
在没有首先创建路径列表的情况下使用路径信息,这需要在第一个之前读取内存中的所有文件转换后的文件被写入。
这是我尝试的:
import json
import dask.bag as db
from dask.distributed import performance_report
from dask.distributed import Client
def transform_data(data):
extracted_at = data.pop("extracted_at")
return dict(extracted_at=extracted_at, data=data)
def transform_file(file):
""" We need to separate json lines, manipulate each record, and return a json string
"""
contents, path = file
data = [
json.dumps(transform_data(json.loads(line)))
for line in contents.replace("}{", "}\n{").splitlines() # fix missing \n between json strings
]
return "\n".join(data), path
def get_paths(path):
return path[-1].replace(".gz", ".jsonl.gz")
if __name__ == "__main__":
client = Client(processes=False, n_workers=4)
b = db.read_text("s3://mybucket/prefix/**/*.gz", include_path=True)
with performance_report():
xformed = b.map(transform_file)
data = xformed.map(lambda x: x[0]) # each item is a tuple of (data, path)
paths = xformed.map(get_paths).compute()
data.to_textfiles(paths)
是否可以在处理文件时写入文件以避免内存问题? bag
不是这个用例的最佳抽象吗?
谢谢!
答案 0 :(得分:0)
是否可以在处理文件时写入文件以避免内存问题?
是的,这是可能的。
<块引用>bag 难道不是这个用例的最佳抽象吗?
我不认为这是最好的情况,因为您正在逐个文件地处理数据,而 bag/dataframe 的想法是将数据视为单个对象。因此,如果您要查询这些文件以获得某些特定结果(如文档中的示例),bag 会很棒。此处最合适的 dask 工具是 delayed
API。