dask包没有使用所有核心?备择方案?

时间:2015-12-03 19:09:58

标签: python json parallel-processing export-to-csv dask

我有一个python脚本,它执行以下操作: 一世。它接受数据的输入文件(通常是嵌套的JSON格式) II。将数据逐行传递给另一个函数,该函数将数据处理成所需的格式 III。最后它将输出写入文件。

这是我当前的简单python行,它可以做到这一点......

def manipulate(line):
    # a pure python function which transforms the data
    # ...
    return manipulated_json

for line in f:
    components.append(manipulate(ujson.loads(line)))
    write_to_csv(components)`

这很有效,但是python GIL将它限制在服务器上的一个核心,它的速度非常慢,特别是对于大量数据。

我通常处理的数据量约为4 gig gzip压缩但偶尔我必须处理数百gig gzip压缩的数据。它不是必需的大数据,但仍无法在内存中进行处理,并且Python的GIL处理速度非常慢。

在寻找优化数据处理的解决方案时,我遇到了dask。虽然PySpark在当时似乎是我的明显解决方案,但是dask的承诺和它的简单性让我受益匪浅,我决定尝试一下。

经过对dask的大量研究以及如何使用它,我整理了一个非常小的脚本来复制我当前的过程。脚本如下所示:

import dask.bag as bag
import json
bag.from_filenames('input.json.gz').map(json.loads).map(lambda x:manipulate(x)).concat().to_dataframe().to_csv('output.csv.gz')`

这可以生成与原始非dask脚本相同的结果,但仍然只在服务器上使用一个CPU 。所以,它根本没有帮助。事实上,它的速度较慢。

我做错了什么?我错过了什么吗?我仍然相当新闻,所以如果我忽略了某些事情或者我应该做一些完全不同的事情,请告诉我。

此外,是否有任何替代方法可以使用服务器的全部容量(即所有CPU)来完成我需要做的事情?

谢谢,

Ť

3 个答案:

答案 0 :(得分:2)

这里的问题是dask.dataframe.to_csv,它迫使你进入单核模式。

我建议使用dask.bag进行阅读和操作,然后并行转储到一堆CSV文件中。转储到许多CSV文件比转储到单个CSV文件更容易协调。

import dask.bag as bag
import json
b = bag.from_filenames('input.json.gz').map(json.loads).map(manipulate).concat()
b.map(lambda t: ','.join(map(str, t)).to_textfiles('out.*.csv').compute()

尝试并行读取单个GZIP文件时可能会出现问题,但上述内容应该可以帮助您入门。

答案 1 :(得分:0)

袋子似乎只与它们所拥有的分区数量平行。

对我来说,跑步

mybag=bag.from_filenames(filename, chunkbytes=1e7)
mybag.npartitions

产量

  

1746

解决了这个问题并使处理完全可并行化。

答案 2 :(得分:0)

如果您提供基于glob的文件名,例如MyFiles-*.csv {d} dataframe.to_csv()您应该能够将数据帧输出到磁盘。 它将创建多个文件而不是1个大型csv文件。请参阅此帖子了解https://groups.google.com/a/continuum.io/forum/#!searchin/blaze-dev/to_csv/blaze-dev/NCQfCoOWEcI/S7fwuCfeCgAJ

MyFiles-0001.csv  
MyFiles-0002.csv 
....