python dask_《使用Python和Dask实现分布式并行计算》2. Introducing Dask(介绍Dask)

本文介绍了Dask的DataFrame API在处理大规模数据时的优势,通过元数据展示了Dask如何处理数据类型推断,并通过实例演示了Dask DataFrame的使用,包括读取CSV文件、计算缺失值、可视化任务图。文章还讨论了Dask的惰性计算、持久化中间结果、任务调度和数据本地性,强调了DAG在分布式计算中的作用和性能优化的重要性。
摘要由CSDN通过智能技术生成

楔子

现在相信你已经对DAG的工作原理有了基本的理解,那么下面来看看Dask如何使用DAG来创建健壮的、可扩展的workload(控制器)。

下面我们要完成两件事:使用Dask的DataFrame API来分析结构化数据集;研究一些有用的诊断工具,并使用low-level Delayed API来创建一个简单的自定义任务图。

import sys

import dask

print(dask.__version__) # 2.28.0

print(sys.version[: 5]) # 3.8.1

你好Dask:看一下你的DataFrame API

任何数据科学项目的一个基本步骤都是对数据集执行探索性分析,在探索性分析期间,你需要检查数据是否存在缺失值、异常值和任何其他数据质量问题。如果出现了脏数据,需要对其进行清洗,以确保对数据所做的任何结论不会受到错误或异常数据的影响。在使用Dask DataFrame API的第一个示例中,我们将逐步读取数据文件,并扫描数据以查找缺失值,并删除由于丢失太多数据或者对分析没有帮助的列。

检测Dask对象的元数据(metadata)

下面我们首先需要读取数据集,关于数据集,书中使用的是上一篇博客中说的NYC停车罚单数据,但是我们这里暂时不使用那个数据集。我们可以在kaggle上下载其它的数据集,这里我下载的是:https://www.kaggle.com/kenshoresearch/kensho-derived-wikimedia-data里面的item.csv。

没有特殊说明,我们的代码都是在jupyter notebook上面运行。

import dask.dataframe as dd

df = dd.read_csv(r"C:\Users\satori\Desktop\item\item.csv")

df

如果你是一个经验丰富的pandas使用者,那么你会发现上面的代码非常的熟悉,因为它们在语法上是等价的。但是结果却不一定是你熟悉的,pandas的DataFrame对象在打印的时候会尝试将数据的开头和结尾显示出来,最上方是列名,左侧是索引。但是我们看到Dask DataFrame在打印的时候会显示元数据,列名在顶部,而下方则是每个列各自的数据类型,因为Dask会非常努力、并且智能地从数据中推断数据类型,就像pandas所做的那样。但是Dask在这方面的能力也是会受到限制的,Dask是用来处理不能被单机读取的中大型数据集的,而pandas是完全基于内存操作,所以它可以轻松而快速地扫描整个数据集,从而判断每个列的最佳数据类型。另一方面,Dask必须能够很好的处理分散在分布式文件系统中多个机器的数据集,因此Dask DataFrame使用随机抽样的方法从一小部分数据样本中分析和推断数据类型。但是这样有一个问题,如果数百万或数十亿行中只有一个异常行,那么这个异常行就不太可能被随机挑选出来,这将导致Dask选择不兼容的数据类型,可能会导致在后面的执行计算中出现错误。因此避免这种情况的最佳实践是显式地设置数据类型,而不是依赖于Dask的推断。

事实上这一点很好理解,因为pandas是将数据全部读取到内存中,即便是分块,它最终也是可以选择一个合适的类型。但是对于Dask而言,显然是没有办法这么做的,因为数据量就已经决定了光靠随机采样是达不到百分之百的准确率。

或者更好的做法是使用能够表示数据类型的二进制文件(比如:Parquet),类型是什么在文件中进行体现,这样就完全可以避免类型推断带来的问题。我们将在后续系列来讨论这个问题,目前我们就让Dask自己推断数据类型。

显然我们来看看Dask DataFrame的输出,因为这和pandas DataFrame的输出还是有很大差别的。Dask DataFrame显示的是元数据信息,它告诉了我们Dask的任务调度器在处理该文件时是如何对任务进行分解的。

npartitions显示了将DataFrame分隔成多少个分区,这里是65个,由于该文件的大小是3.85GB,在65个分区中,每个分区的大小大概是60.65MB。这意味着Dask不是一次性将文件加载到内存中,而是每个Dask工作线程一次处理一个60.65MB的文件块。而且dd.read_csv在读取这个大文件时,几乎是瞬间完成的,这也说明了该函数在读取csv文件时会执行懒加载。

Dask将文件分成可以独立处理的多个小块,而不是马上将整个文件读取到内存中,而这些块就叫做分区。而Dask DataFrame中的每一个分区,都相当于是一个较小的pandas DataFrame。

所以Dask是将大文件分割成多个分区,一次处理一个分区。

图中的Dask DataFrame是由两个分区组成,因此单个Dask DataFrame由两个较小的pandas DataFrame组成,每个分区都可以加载到内存中进行处理。工作节点先拾取分区1进行处理,然后将结果保存在临时存储空间中。然后拾取分区2进行处理,也将结果保存在一个临时空间中,然后将两个结果合并并返回给我们。因为工作节点一次可以处理较小的数据片段,所以可以将工作分配个多个机器,或者在本地的情况下,也可以在非常大的数据集上继续工作,而不会导致内存不足产生的错误(内存溢出)。

注意df返回的元数据,我们还有一个信息没有说,就是最下面的65 tasks,这表示Dask DataFrame由65个任务组成。这表示Dask创建了一个有65个节点的有向无环图来处理

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值