我正试图在Dask Dataframe上完成一些操作,但我并不完全理解这样做的最佳方法。
例如,我正在从镶木地板中读取一个dask数据框,我想在第一列中添加一个单元,在第二列中添加两个单元:
import dask.dataframe as dd
ddf = dd.read_parquet('dataframe')
ddf['a'] = ddf['a'] + 1
ddf['b'] = ddf['b'] + 2
ddf.visualize()
Here是此计算的图表。 (数据框是使用2个分区创建的。)
可以看出,这两个操作是一个接一个地完成的,我们知道它们可以并行完成(至少部分),因为它们正在向不同的列添加一些值。
因此,我试图通过使用延迟函数来对这些操作进行并行化:
from dask import delayed
import dask.dataframe as dd
@delayed
def increment(df, x, val):
print('Type: ',type(df))
df[x] = df[x] + val
return df
@delayed
def overwrite(df1 , df2, col):
df1[col] = df2[col]
return df1
ddf = dd.read_parquet('dataframe')
op1 = increment(ddf[['a']], 'a', 1)
op2 = increment(ddf[['b']], 'b', 2)
op3 = overwrite(ddf, op1, 'a')
op4 = overwrite(op3, op2, 'b')
op4.visualize()
Here是此计算的图表,可以看出,工作的某些部分正在并行完成。当然,这些操作非常简单,这是一种矫枉过正,但这只是为了证明这一点。
但是,我在increment
函数中打印输入数据框的类型,令我惊讶的是,当我运行op4.compute()
时,类型为pandas.core.frame.DataFrame
,而我正在等待它是dask.dataframe.core.DataFrame
。
然后我决定delay
镶木地板文件:
@delayed
def read(name):
return dd.read_parquet(name)
ddf = read('dataframe')
op1 = increment(ddf[['a']], 'a', 1)
op2 = increment(ddf[['b']], 'b', 2)
op3 = overwrite(ddf, op1, 'a')
op4 = overwrite(op3, op2, 'b')
op4.visualize()
graph显示作业正在并行完成,当我运行op4.compute()
时increment
函数中输入数据框的类型为dask.dataframe.core.DataFrame
我是什么期待。
但是,op4
的类型是dask.delayed.Delayed
,这意味着当我计算它时,我得到dask.dataframe.core.DataFrame
,因此,为了获得最终的数据帧,有必要应用计算两次:
op4.compute().compute()
a b
index
0 2 3
1 2 3
2 2 3
3 2 3
4 2 3
5 2 3
6 2 3
7 2 3
8 2 3
9 2 3
我们还以手动方式(使用字典)创建了图形,如文档中所示。但是,我们希望了解上面显示的延迟版本是否是处理这种情况的最佳方法。在线文档似乎只显示与值列表一起使用的延迟方法,而不是数据帧。
总结一下,为dask数据帧分段作业的最佳方法是什么?