将迭代器传递给dask.delayed函数

时间:2018-11-10 07:04:02

标签: python dask dask-delayed

我试图将迭代器通过(非标准)类似文件的对象传递给dask.delayed函数。当我尝试compute()时,我从dask收到了以下消息,并在下面进行了回溯。

distributed.protocol.pickle - INFO - Failed to serialize 
  ([<items>, ... ], OrderedDict(..)).
Exception: self.ptr cannot be converted to a Python object for pickling

Traceback (most recent call last):
  File "/home/user/miniconda3/lib/python3.6/site-packages/distributed/protocol/pickle.py", line 38, in dumps
    result = pickle.dumps(x, protocol=pickle.HIGHEST_PROTOCOL)
  File "stringsource", line 2, in pysam.libcbcf.VariantRecord.__reduce_cython__
TypeError: self.ptr cannot be converted to a Python object for pickling

源代码的相应部分如下所示:

delayed(to_arrow)(vf.fetch(..), ordered_dict)

vf是类似文件的对象,vf.fetch(..)返回文件中存在的记录的迭代器(这是VCF file,而我正在使用{{3 }}库以供阅读。我希望这可以提供足够的背景信息。

来自dask的消息显示迭代发生在函数调用期间而不是函数内部,这使我相信传递迭代器可能不可行。因此,我对sum(range(..))进行了快速检查,这似乎可行。现在我很困惑,我想念什么?

为此提供一个最小工作示例有点困难。但也许以下方法会有所帮助。

  1. pysam下载一个VCF文件(及其索引):例如ALL.chrY*vcf.gz{,.tbi}
  2. pip3 install --user pysam
  3. 打开文件:vf = VariantFile('/path/to/file.vcf.gz', mode='r')
  4. 像这样的迭代器:vf.fetch("Y", 2_600_000, 2_700_000)
  5. 对于延迟功能,您可以有一个空循环。

1 个答案:

答案 0 :(得分:1)

简短的答案是:重构延迟的函数,以使文件打开阶段发生在函数内 ,而您传递了指向该特定文件所需的参数(例如path)。

如果您有兴趣,可以研究一下Dask在内部如何做到这一点,即类dask.bytes.core.OpenFile,它是一个可序列化的东西,会推迟打开,直到在with块中使用它为止。这是一种方便的方法,但是您可以做一些简单的事情。