我试图将迭代器通过(非标准)类似文件的对象传递给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(..))
进行了快速检查,这似乎可行。现在我很困惑,我想念什么?
为此提供一个最小工作示例有点困难。但也许以下方法会有所帮助。
pysam
下载一个VCF文件(及其索引):例如ALL.chrY*vcf.gz{,.tbi}
pip3 install --user pysam
vf = VariantFile('/path/to/file.vcf.gz', mode='r')
vf.fetch("Y", 2_600_000, 2_700_000)
答案 0 :(得分:1)
简短的答案是:重构延迟的函数,以使文件打开阶段发生在函数内 ,而您传递了指向该特定文件所需的参数(例如path)。
如果您有兴趣,可以研究一下Dask在内部如何做到这一点,即类dask.bytes.core.OpenFile
,它是一个可序列化的东西,会推迟打开,直到在with
块中使用它为止。这是一种方便的方法,但是您可以做一些简单的事情。