Dask Bag 实现了对通用 Python 对象集合的操作,如 mapfilterfoldgroupby。它使用 Python 迭代器以较小的内存占用并行执行这些操作。它类似于 PyToolz 的并行版本,或者是 PySpark RDD 的 Pythonic 版本。

示例

访问 http://www.aidoczh.com/dask-examples/ bag.html 查看并运行使用 Dask Bag 的示例。

设计

Dask 包协调许多 Python 列表或迭代器,每个列表或迭代器形成一个更大集合的分区。

常见用途

Dask 包通常用于并行化对非结构化或半结构化数据的简单计算,如文本数据、日志文件、JSON 记录或用户定义的 Python 对象。

执行

在袋子上执行提供两个好处:

  1. 并行:数据被分割,允许多个核心或机器并行执行

  2. 迭代:数据处理是惰性的,允许在单个分区内甚至在单台机器上平滑执行大于内存的数据。

默认调度器

默认情况下,dask.bag 使用 dask.multiprocessing 进行计算。 因此,Dask 绕过了 GIL 并使用纯 Python 对象上的多个内核。 然而,Dask Bag 在包含大量工作节点间通信的计算中表现不佳。 对于常见的操作,这通常不是问题,因为大多数 Dask Bag 工作流程都是令人尴尬的并行或导致工作节点间数据移动很少的归约操作。

洗牌

一些操作,如 groupby,需要大量的工作节点间通信。在单机上,Dask 使用 partd 来执行高效、并行、溢出到磁盘的洗牌操作。在集群环境中工作时,Dask 使用基于任务的洗牌。

这些洗牌操作是昂贵的,最好由 dask.dataframe 这样的项目来处理。最好使用 dask.bag 来清理和处理数据,然后在进行需要洗牌步骤的更复杂操作之前将其转换为数组或 DataFrame。

已知限制

包提供了非常通用的计算(任何 Python 函数)。这种通用性是有代价的。包有以下已知限制:

  1. 默认情况下,它们依赖于多进程调度器,该调度器有其自身的一组已知限制(参见 共享内存

  2. 袋子是不可变的,因此你不能更改单个元素

  3. 在相同的方式下,包操作往往比数组/DataFrame计算慢,就像标准Python容器往往比NumPy数组和Pandas DataFrames慢一样。

  4. Bag 的 groupby 速度较慢。如果可能,你应该尝试使用 Bag 的 foldby。不过,使用 foldby 需要更多的思考。

名称

Bag 是允许重复的无序集合的数学名称。它是 multiset 的一个友好同义词。Bag 或 multiset 是集合概念的泛化,与集合不同,它允许 multiset 的元素有多个实例:

  • list: 有序 集合 可重复, [1, 2, 3, 2]

  • set: 无序 集合 无重复, {1, 2, 3}

  • bag: 无序 集合 带重复, {1, 2, 2, 3}

所以,一个袋子就像一个列表,但它不保证元素之间的顺序。可以有重复的元素,但你不能请求第i个元素。