我有一个数据集,存储在一个制表符分隔的文本文件中。该文件如下所示:
date time temperature
2010-01-01 12:00:00 10.0000
...
其中temperature
列包含以摄氏度(°C)为单位的值。
我使用Dask计算每日平均温度。这是我的代码:
from dask.distributed import Client
import dask.dataframe as dd
client = Client("<scheduler URL")
inputDataFrame = dd.read_table("<input file>").drop('time', axis=1)
groupedData = inputDataFrame.groupby('date')
meanDataframe = groupedData.mean()
result = meanDataframe.compute()
result.to_csv('result.out', sep='\t')
client.close()
为了提高程序的性能,我想了解由Dask数据帧引起的数据流。
read_table()
如何将文本文件读入数据框中?客户端是否读取整个文本文件并将数据发送到计划程序,该程序对数据进行分区并将其发送给工作程序?还是每个工作人员都直接从文本文件中读取其工作的数据分区?drop()
),整个中间数据帧是否已发送回客户端,然后又发送给工作人员进行进一步处理?我提出这个问题的原因是,如果我使用Pandas运行类似的程序,则计算速度大约快两倍,并且我试图了解是什么导致了Dask的开销。由于结果数据帧的大小与输入数据的大小相比非常小,我认为在客户端,调度程序和工作程序之间移动输入数据和中间数据会导致相当大的开销。
答案 0 :(得分:1)
1)工人读取数据。客户端确实会提前读取一些信息,以找出列名和类型,并且可以选择查找用于分隔文件的行定界符。请注意,所有工作人员都必须能够访问感兴趣的文件,这在群集上工作时可能需要某些共享文件系统。
2),3)实际上,drop
,groupby
和mean
方法根本不生成中间数据帧,它们只是累加要执行的操作图(即,他们懒惰)。您可以安排这些步骤的时间,看看它们很快。在执行期间,对工人进行中间加工,根据需要将其复制到其他工人,并尽快将其丢弃。除非您明确要求,否则永远不会复制到调度程序或客户端。
因此,从根本上讲,您可以通过查看dashboard来研究性能或最佳操作。
有许多因素决定着事情进展的速度:这些流程可能共享一个IO通道;有些任务不释放GIL,因此线程并行性很差;组的数量将极大地影响将数据改组为组的数量……加上调度程序执行的每个任务总是会有一些开销。
由于Pandas高效,因此对于数据容易放入内存的情况,与Dask相比,它的性能也就不足为奇了。