【数据分析】Python使用Dask Dataframes并行数据分析

#仅通过引用返回x> 5的行(写入它们会改变原始df)
df2 = df.loc[df['x'] > 5]
#通过引用仅返回x为0,1,2,3或4的行
df3 = df.x.isin(range(4))
#只返回x> 5的行,只读参考(无法写入)
df4 = df[df['x']>5]
[/code]

## 如何使用Dask Dataframes

Dask Dataframes与Pandas Dataframes具有相同的API,除了聚合和 _apply_ s被懒惰地评估,并且需要通过调用
_compute_ 方法来计算。为了生成Dask Dataframe,您可以像在Pandas中一样调用 _read_csv_
方法,或者,如果给出Pandas Dataframe _df_ ,您只需调用

```code
dd = ddf.from_pandas(df,npartitions = N)
[/code]

其中 _ddf_ 是您导入Dask Dataframes的名称,而 _npartitions_ 是一个参数,告诉Dataframe如何对其进行分区。

根据StackOverflow的说法,建议将Dataframe划分为与计算机所拥有的核心数量相同的分区,或者是该数量的几倍,因为每个分区将在不同的线程上运行,如果有的话,它们之间的通信将变得过于昂贵许多。

## 弄脏:让我们来做基准!

我制作了一个Jupyter笔记本来试用这个框架,并 [ 在Github ](https://github.com/StrikingLoo/dask-
dataframe-benchmarking) 上 [ 提供 ](https://github.com/StrikingLoo/dask-
dataframe-benchmarking) 它,以防你想要检查它甚至自己运行它。

我运行的基准测试可以在Github的笔记本中找到,但主要有:

```code
def get_big_mean():
return dfn.salary.mean().compute()
def get_big_mean_old():
return df3.salary.mean()

def get_big_max():
return dfn.salary.max().compute()
def get_big_max_old():
return df3.salary.max()

def get_big_sum():
return dfn.salary.sum().compute()
def get_big_sum_old():
return df3.salary.sum()

def filter_df():
df = dfn[dfn['salary']>5000]
def filter_df_old():
df = df3[df3['salary']>5000]
[/code]

这里 _df3_ 是一个普通的Pandas Dataframe,拥有2500万行,使用 [ 上一篇文章中
](https://github.com/StrikingLoo/pandas_workshop) 的脚本生成(列是 _名称,姓氏_ 和 _薪水_
,从列表中随机抽样)。我拿了50行数据集并连接了500000次,因为我对分析 _本身_ 并不太感兴趣,但只是在运行它的时候。

_dfn_ 就是基于 _df3_ 的Dask Dataframe 。

## 第一批结果:不太乐观

我首先尝试使用3个分区进行测试,因为我只有4个内核,并且不想过度使用我的PC。我和Dask的结果非常差,并且还要等很多才能得到它们,但我担心这可能是因为我制作的分区太少了:

```code
204.313940048 seconds for get_big_mean
39.7543280125 seconds for get_big_mean_old
[/code]

```code
131.600986004 seconds for get_big_max
43.7621600628 seconds for get_big_max_old
[/code]

```code
120.027213097 seconds for get_big_sum
7.49701309204 seconds for get_big_sum_old
[/code]

```code
0.581165790558 seconds for filter_df
226.700095892 seconds for filter_df_old
[/code]

当我使用Dask时,您可以看到大多数操作变得慢得多。这给了我一些暗示我可能不得不使用更多分区。产生惰性评估所花费的金额也可以忽略不计(在某些情况下不到半秒),所以如果重复使用它,它就不会随着时间的推移而摊销。

我也用 _apply_ 方法尝试了这个测试:

```code
def f(x):
return (13*x+5)%7

def apply_random_old():
df3['random']= df3['salary'].apply(f)

def apply_random():
dfn['random']= dfn['salary'].apply(f).compute()
[/code]

并有非常相似的结果:

```code
369.541605949 seconds for apply_random
157.643756866 seconds for apply_random_old
[/code]

因此,一般来说,大多数操作的速度都是原始操作的两倍,尽管过滤器的速度要快得多。我担心也许我应该在那个上调用 _计算器_ ,所以把这个结果带上一粒盐。

## 更多分区:惊人的加速

在这些令人沮丧的结果之后,我决定我可能只是没有使用足够的分区。毕竟,这一点的重点是并行运行,所以也许我只需要更多并行化?所以我尝试了8个分区的相同测试,这就是我得到的(我省略了非并行数据帧的结果,因为它们基本相同):

```code
3.08352184296 seconds for get_big_mean
1.3314101696 seconds for get_big_max
1.21639800072 seconds for get_big_sum
0.228978157043 seconds for filter_df
[/code]

```code
112.135010004 seconds for apply_random
50.2007009983 seconds for value_count_test
[/code]

那就对了!大多数操作的运行速度比常规Dataframe快十倍,甚至 _申请_ 速度也更快!我还运行了 _value_count_ 测试, _它只_ 调用
_salary_ 系列上的 _value_count_
方法。对于上下文,请记住,在经过十分钟的等待后,我在常规Dataframe上运行此测试时必须终止该过程。这次只用了50秒!
所以基本上我只是使用错误的工具,而且它非常快。比常规Dataframe快很多。

## 最后

鉴于我们刚刚在一台相当旧的4核PC上运行了2500万行,我可以看到这在行业中将是多么巨大。所以我的建议是在下次必须在本地或从单个AWS实例处理数据集时尝试此框架。这很快。

原文: [ https://towardsdatascience.com/trying-out-dask-dataframes-in-python-for-
fast-data-analysis-in-parallel-aa960c18a915
](https://towardsdatascience.com/trying-out-dask-dataframes-in-python-for-
fast-data-analysis-in-parallel-aa960c18a915)


![在这里插入图片描述](https://img-blog.csdnimg.cn/20210608151750993.gif)

posted @ 2021-06-29 19:34  zsfxg  阅读(261)  评论(0)    收藏  举报