mcpField
D
dask

dask

github.com/leonchaox数据与数据库99470 次安装15 周前更新
代码仓库

关于 dask

Dask 技能介绍 Python 并行与分布式计算库,面向需要处理超出内存的数据或扩展计算的开发者,提供 DataFrame、Array、Bag 和任务调度等组件。

主要功能

  1. 01并行处理表格数据和数组
  2. 02以分块方式处理超内存数据集
  3. 03使用 Bag 处理文本、JSON 和日志
  4. 04通过 Futures 构建任务依赖工作流
  5. 05选择线程、进程或分布式调度器

适用场景

  1. 01并行处理多份 CSV 或 Parquet 文件
  2. 02对大型科学数组执行分块计算
  3. 03清理日志或 JSON 后转换为表格数据
  4. 04在多核或多机环境运行自定义任务

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/leonchaox/qinyan-academic-skills --skill dask

安装后在 Claude Code 中输入/dask确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
arrays.md
bags.md
best-practices.md
dataframes.md
futures.md
schedulers.md

详细介绍

Dask

概述

Dask 是一个用于并行和分布式计算的 Python 库,可提供三项关键能力:

  • 超出内存容量的执行:在单台机器上处理超出可用 RAM 容量的数据
  • 并行处理:利用多个核心提升计算速度
  • 分布式计算:支持在多台机器上处理 TB 级数据集

Dask 可从笔记本电脑(处理约 100 GiB)扩展到集群(处理约 100 TiB),同时保留熟悉的 Python API。

何时使用此技能

在以下情况下应使用此技能:

  • 处理超出可用 RAM 容量的数据集
  • 将 pandas 或 NumPy 操作扩展到更大的数据集
  • 并行化计算以提升性能
  • 高效处理多个文件(CSV、Parquet、JSON、文本日志)
  • 构建具有任务依赖关系的自定义并行工作流
  • 在多个核心或机器之间分配工作负载

核心能力

Dask 提供五个主要组件,分别适用于不同的使用场景:

1. DataFrames - 并行 Pandas 操作

用途:通过并行处理,将 pandas 操作扩展到更大的数据集。

适用场景:

  • 表格数据超出可用 RAM 容量
  • 需要同时处理多个 CSV/Parquet 文件
  • Pandas 操作速度较慢,需要并行化
  • 从 pandas 原型扩展到生产环境

参考文档:如需全面了解 Dask DataFrames,请参阅 references/dataframes.md,其中包括:

  • 读取数据(单个文件、多个文件、glob 模式)
  • 常见操作(筛选、groupby、连接、聚合)
  • 使用 map_partitions 执行自定义操作
  • 性能优化技巧
  • 常见模式(ETL、时间序列、多文件处理)

快速示例:

import dask.dataframe as dd

# Read multiple files as single DataFrame
ddf = dd.read_csv('data/2024-*.csv')

# Operations are lazy until compute()
filtered = ddf[ddf['value'] > 100]
result = filtered.groupby('category').mean().compute()

要点:

  • 操作是惰性的(构建任务图),直到调用 .compute()
  • 使用 map_partitions 高效执行自定义操作
  • 处理来自其他来源的结构化数据时,尽早转换为 DataFrame
2. Arrays - 并行 NumPy 操作

用途:使用分块算法,将 NumPy 的能力扩展到超出内存容量的数据集。

适用场景:

  • 数组超出可用 RAM 容量
  • NumPy 操作需要并行化
  • 处理科学数据集(HDF5、Zarr、NetCDF)
  • 需要并行线性代数或数组操作

参考文档:如需全面了解 Dask Arrays,请参阅 references/arrays.md,其中包括:

  • 创建数组(来自 NumPy、随机数据、磁盘)
  • 分块策略和优化
  • 常见操作(算术、归约、线性代数)
  • 使用 map_blocks 执行自定义操作
  • 与 HDF5、Zarr 和 XArray 集成

快速示例:

import dask.array as da

# Create large array with chunks
x = da.random.random((100000, 100000), chunks=(10000, 10000))

# Operations are lazy
y = x + 100
z = y.mean(axis=0)

# Compute result
result = z.compute()

要点:

  • 分块大小至关重要(目标是每块约 100 MB)
  • 操作会并行处理各个数据块
  • 根据需要重新分块,以高效执行操作
  • 使用 map_blocks 执行 Dask 中不可用的操作
3. Bags - 非结构化数据的并行处理

用途:使用函数式操作处理非结构化或半结构化数据(文本、JSON、日志)。

适用场景:

  • 处理文本文件、日志或 JSON 记录
  • 在结构化分析前进行数据清理和 ETL
  • 处理无法适配数组或数据框格式的 Python 对象
  • 需要节省内存的流式处理

参考文档:如需全面了解 Dask Bags,请参阅 references/bags.md,其中包括:

  • 读取文本和 JSON 文件
  • 函数式操作(map、filter、fold、groupby)
  • 转换为 DataFrames
  • 常见模式(日志分析、JSON 处理、文本处理)
  • 性能注意事项

快速示例:

import dask.bag as db
import json

# Read and parse JSON files
bag = db.read_text('logs/*.json').map(json.loads)

# Filter and transform
valid = bag.filter(lambda x: x['status'] == 'valid')
processed = valid.map(lambda x: {'id': x['id'], 'value': x['value']})

# Convert to DataFrame for analysis
ddf = processed.to_dataframe()

要点:

  • 用于初始数据清理,然后转换为 DataFrame/Array
  • 使用 foldby 替代 groupby,以获得更好的性能
  • 操作采用流式处理,且节省内存
  • 转换为结构化格式(DataFrame),以执行复杂操作
4. Futures - 基于任务的并行化

用途:构建自定义并行工作流,精细控制任务执行及其依赖关系。

适用场景:

  • 构建动态、不断演进的工作流
  • 需要立即执行任务(而非惰性执行)
  • 计算依赖于运行时条件
  • 实现自定义并行算法
  • 需要有状态计算

参考文档:如需全面了解 Dask Futures,请参阅 references/futures.md,其中包括:

  • 设置分布式客户端
  • 提交任务并使用 futures
  • 任务依赖与数据传输
  • 高级协调(队列、锁、事件、Actor)
  • 常见模式(参数扫描、动态任务、迭代算法)

快速示例:

from dask.distributed import Client

client = Client()  # Create local cluster

# Submit tasks (executes immediately)
def process(x):
    return x ** 2

futures = client.map(process, range(100))

# Gather results
results = client.gather(futures)

client.close()

要点:

  • 需要分布式客户端(即使只使用单台机器)
  • 提交任务后会立即执行
  • 预先分发大型数据,避免重复传输
  • 每个任务的开销约为 1 ms(不适合数百万个微小任务)
  • 有状态工作流请使用 Actor
5. Schedulers - 执行后端

用途:控制 Dask 任务的执行方式和执行位置(线程、进程、分布式)。

如何选择 Scheduler:

  • Threads(默认):NumPy/Pandas 操作、会释放 GIL 的库、可受益于共享内存的任务
  • Processes:纯 Python 代码、文本处理、受 GIL 限制的操作
  • Synchronous:使用 pdb 调试、性能分析、理解错误
  • Distributed:需要仪表板、多机器集群或高级功能

参考文档:如需全面了解 Dask Schedulers,请参阅 references/schedulers.md,其中包括:

  • Scheduler 的详细说明和特性
  • 配置方法(全局、上下文管理器、每次计算)
  • 性能考量和开销
  • 常见模式和故障排除
  • 用于优化性能的线程配置

快速示例:

import dask
import dask.dataframe as dd

# Use threads for DataFrame (default, good for numeric)
ddf = dd.read_csv('data.csv')
result1 = ddf.mean().compute()  # Uses threads

# Use processes for Python-heavy work
import dask.bag as db
bag = db.read_text('logs/*.txt')
result2 = bag.map(python_function).compute(scheduler='processes')

# Use synchronous for debugging
dask.config.set(scheduler='synchronous')
result3 = problematic_computation.compute()  # Can use pdb

# Use distributed for monitoring and scaling
from dask.distributed import Client
client = Client()
result4 = computation.compute()  # Uses distributed with dashboard

要点:

  • Threads:开销最低(约 10 µs/任务),最适合数值计算
  • Processes:可避免 GIL(约 10 ms/任务),最适合 Python 计算
  • Distributed:提供监控仪表板(约 1 ms/任务),可扩展到集群
  • 可针对单次计算或全局切换 Scheduler

最佳实践

如需全面了解性能优化、内存管理策略和需要避免的常见陷阱,请参阅 references/best-practices.md。核心原则包括:

从简单方案开始

使用 Dask 之前,请先考虑:

  • 更好的算法
  • 高效的文件格式(用 Parquet 代替 CSV)
  • 编译代码(Numba、Cython)
  • 数据采样
关键性能规则

1. 不要先在本地加载数据,再交给 Dask

# Wrong: Loads all data in memory first
import pandas as pd
df = pd.read_csv('large.csv')
ddf = dd.from_pandas(df, npartitions=10)

# Correct: Let Dask handle loading
import dask.dataframe as dd
ddf = dd.read_csv('large.csv')

2. 避免反复调用 compute()

# Wrong: Each compute is separate
for item in items:
    result = dask_computation(item).compute()

# Correct: Single compute for all
computations = [dask_computation(item) for item in items]
results = dask.compute(*computations)

3. 不要构建过大的任务图

  • 如果任务数达到数百万,请增大分块大小
  • 使用 map_partitions/map_blocks 融合操作
  • 检查任务图大小:len(ddf.__dask_graph__())

4. 选择合适的分块大小

  • 目标:每个分块约 100 MB(或工作节点内存中每个核心对应 10 个分块)
  • 过大:内存溢出
  • 过小:调度开销增加

5. 使用仪表板

from dask.distributed import Client
client = Client()
print(client.dashboard_link)  # Monitor performance, identify bottlenecks

常见工作流模式

ETL 流水线
import dask.dataframe as dd

# Extract: Read data
ddf = dd.read_csv('raw_data/*.csv')

# Transform: Clean and process
ddf = ddf[ddf['status'] == 'valid']
ddf['amount'] = ddf['amount'].astype('float64')
ddf = ddf.dropna(subset=['important_col'])

# Load: Aggregate and save
summary = ddf.groupby('category').agg({'amount': ['sum', 'mean']})
summary.to_parquet('output/summary.parquet')
非结构化到结构化数据流水线
import dask.bag as db
import json

# Start with Bag for unstructured data
bag = db.read_text('logs/*.json').map(json.loads)
bag = bag.filter(lambda x: x['status'] == 'valid')

# Convert to DataFrame for structured analysis
ddf = bag.to_dataframe()
result = ddf.groupby('category').mean().compute()
大规模数组计算
import dask.array as da

# Load or create large array
x = da.from_zarr('large_dataset.zarr')

# Process in chunks
normalized = (x - x.mean()) / x.std()

# Save result
da.to_zarr(normalized, 'normalized.zarr')
自定义并行工作流
from dask.distributed import Client

client = Client()

# Scatter large dataset once
data = client.scatter(large_dataset)

# Process in parallel with dependencies
futures = []
for param in parameters:
    future = client.submit(process, data, param)
    futures.append(future)

# Gather results
results = client.gather(futures)

选择合适的组件

使用以下决策指南选择合适的 Dask 组件:

数据类型:

  • 表格数据 → DataFrames
  • 数值数组 → Arrays
  • 文本/JSON/日志 → Bags(然后转换为 DataFrame)
  • 自定义 Python 对象 → Bags 或 Futures

操作类型:

  • 标准 pandas 操作 → DataFrames
  • 标准 NumPy 操作 → Arrays
  • 自定义并行任务 → Futures
  • 文本处理/ETL → Bags

控制级别:

  • 高级、自动 → DataFrames/Arrays
  • 底层、手动 → Futures

工作流类型:

  • 静态计算图 → DataFrames/Arrays/Bags
  • 动态、不断演进 → Futures

集成注意事项

文件格式
  • 高效:Parquet、HDF5、Zarr(列式、压缩、适合并行处理)
  • 兼容但较慢:CSV(仅用于初始导入)
  • 适用于数组:HDF5、Zarr、NetCDF
集合之间的转换
# Bag → DataFrame
ddf = bag.to_dataframe()

# DataFrame → Array (for numeric data)
arr = ddf.to_dask_array(lengths=True)

# Array → DataFrame
ddf = dd.from_dask_array(arr, columns=['col1', 'col2'])
与其他库配合使用
  • XArray:为 Dask 数组添加带标签的维度(地理空间、成像)
  • Dask-ML:使用兼容 scikit-learn 的 API 进行机器学习
  • Distributed:高级集群管理和监控

调试与开发

迭代式开发工作流
  1. 使用同步调度器在小型数据上测试:
dask.config.set(scheduler='synchronous')
result = computation.compute()  # Can use pdb, easy debugging
  1. 使用线程在样本上验证:
sample = ddf.head(1000)  # Small sample
# Test logic, then scale to full dataset
  1. 使用 distributed 扩展规模并进行监控:
from dask.distributed import Client
client = Client()
print(client.dashboard_link)  # Monitor performance
result = computation.compute()
常见问题

内存错误:

  • 减小分块大小
  • 有策略地使用 persist(),并在用完后删除
  • 检查自定义函数是否存在内存泄漏

启动缓慢:

  • 任务图过大(增大分块大小)
  • 使用 map_partitions 或 map_blocks 减少任务数量

并行化效果不佳:

  • 分块过大(增加分区数量)
  • 使用线程运行 Python 代码(切换到进程)
  • 数据依赖阻碍并行处理

参考文件

如需详细信息,可按需阅读所有参考文档文件:

  • references/dataframes.md - 完整的 Dask DataFrame 指南
  • references/arrays.md - 完整的 Dask Array 指南
  • references/bags.md - 完整的 Dask Bag 指南
  • references/futures.md - 完整的 Dask Futures 和分布式计算指南
  • references/schedulers.md - 完整的调度器选择与配置指南
  • references/best-practices.md - 全面的性能优化与故障排除指南

当用户需要了解此处快速指南未涵盖的特定 Dask 组件、操作或模式的详细信息时,请加载这些文件。

评论

支持 Markdown