【问题标题】:Python Multiprocessing - Can we pass an (itertools.islice) iterable directly to pool.imap whithout converting to a list?Python Multiprocessing - 我们可以将(itertools.islice)可迭代直接传递给pool.imap而不转换为列表吗?
【发布时间】:2020-12-09 04:49:42
【问题描述】:

在从 DB2 中读取一个大表(有些表有 1 亿个)后,我使用 itertools.islice 将生成器对象转换为迭代器。我将迭代器传递给 multiprocessing pool.map,它调用一个函数将这些块并行提取到 CSV。

它可以工作,但在并行运行开始之前,python pool.map 将 ITERATOR 转换为消耗大量时间的 LIST。有没有办法可以避免创建此列表或更​​快地转换为列表?我也尝试过使用 POOL.IMAP,但是当我运行程序时,我的笔记本内核死了。要使用 IMAP,我必须将迭代器转换为需要时间的列表。有什么想法吗?

generator_df = pd.read_sql(query2, test_connection_forbankcv_connection, chunksize = 5000)
iterable_slice = list(it.islice(generator_df, slice_start,slice_end))
results = p.imap(chunk_to_csv, iterable_slice, 1) 

【问题讨论】:

  • 你会考虑使用 Spark 吗? Pyspark 如果你更喜欢 python。它会让您的生活更轻松。
  • _map_async 的来源表明它要求传递的iterable 具有__len__ 属性,如果没有,则将其转换为列表。所有map 变体似乎都委托给该方法,因此似乎没有办法绕过它。您也许可以使用 apply_async 来装配一些东西,您自己处理迭代。
  • @Carcigenicate。希望用__len__ 实现迭代器会很难吗?
  • “笔记本内核死机”的信息不是很丰富。究竟会发生什么——最好在不隐藏在 GUI 中的 Python 进程中进行测试?
  • @MadPhysicist 我想在这种特殊情况下,您可以在一个切片对象上创建一个包装器,该对象公开一个长度属性,因为可以计算长度。但总的来说,迭代器可以是无限的,因此长度可能没有意义。

标签: python multithreading iterator multiprocessing generator


【解决方案1】:

我马上承认,这个解决方案有一些问题,但它显示了基本思想:

import itertools
from typing import Iterable
from multiprocessing import Pool

class Lengthed_ISlice:
    def __init__(self, iterable: Iterable, start: int, stop: int):
        self._start = start
        self._stop = stop
        self._islice = itertools.islice(iterable, self._start, self._stop)

    def __len__(self):
        return self._stop - self._start

    def __iter__(self):
        return iter(self._islice)

这是一个对 islice 对象的瘦包装,它实现了所需的 __len__ 方法,以便它可以与 Pool 的 map 方法一起使用:

def double(n):
    return n * 2

my_list = list(range(10, 100))

with Pool() as p:
    print(p.map(double, Lengthed_ISlice(my_list, 2, 9)))
    # Prints [24, 26, 28, 30, 32, 34, 36]

主要问题:

  • 除了__iter__ 之外,它没有正确地将任何功能委托给底层islice。如果您在扩展使用 this 时/如果您收到有关缺少方法的错误,则需要实施正确的方法。
  • 为简洁起见,我没有考虑步骤,因为您没有使用非默认步骤,而且它们会使数学稍微复杂化。
  • 我不担心使用Iterable 的通用参数。如果您想要更好的类型提示,您应该为构造函数参数和__iter__ 引入TypeVar。

【讨论】:

  • 非常感谢您的快速回复。我会尽力让你知道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多