Pyspark 在分割柱和编写拼花文件时,大量时间会增加

Pyspark 在分割柱和编写拼花文件时,大量时间会增加,pyspark,Pyspark,我处理临床数据,所以很抱歉我不能显示任何输出,因为它是HIPAA规定的,但我会尽我所能填补任何空白 我刚毕业于数据科学专业,从来没有花太多时间研究过spark系统,但我现在担任新的角色。我们正在从一个我将调用udf_函数的函数中收集输出,该函数从医生那里获取临床记录(报告),并返回函数从python函数调用_函数中定义的输出。下面是我用来完成这项任务的代码 def call_function(report): //python code that generates a list of

我处理临床数据,所以很抱歉我不能显示任何输出,因为它是HIPAA规定的,但我会尽我所能填补任何空白

我刚毕业于数据科学专业,从来没有花太多时间研究过spark系统,但我现在担任新的角色。我们正在从一个我将调用udf_函数的函数中收集输出,该函数从医生那里获取临床记录(
报告
),并返回函数从python函数
调用_函数
中定义的输出。下面是我用来完成这项任务的代码

def call_function(report):

    //python code that generates a list of a,b,c, which I 
      join together to return a string of the combined list items

    a=  ",".join(a)
    b= ",".join(b)
    c= ",".join(c)
    return [a,b,c]


udf_function= udf(lambda y: call_function(y), ArrayType(StringType()))

mid_frame = df.select('report',
                       udf_function('report').alias('udf_output')
                     )
这将返回一个长度为3的数组,其中包含有关函数返回的信息的字符串。前几天,我选择了25000条记录,在GCP上的一个30节点集群(20个工人,10个抢先)上仅用了3个多小时就完成了运行

我对代码做了一些修改,以便从数组中解析出三个对象,因为这三个对象包含我们要进一步分析的不同类型的信息,我将其称为
a
b
c
(再次,如果这是模糊的,我很抱歉;我正在尽可能地保持实际数据的表面层次)。前3个小时的运行没有写出任何文件,因为我正在测试系统需要多长时间

output = mid_frame.select('report',
                           mid_frame['udf_output'].getItem(0).alias('a'),
                           mid_frame['udf_output'].getItem(1).alias('b'),
                           mid_frame['udf_output'].getItem(2).alias('c')
                          )
output_frame.show()
output_frame.write.parquet(data_bucket)
解析输出和写入文件的任务额外花费了48小时。我想如果我处理大文件的话,我可以忍受这段时间的损失,但是输出是4个拼花文件,总共24.06MB。查看作业日志,编写过程本身只花了大约20个小时

显然,我引入了一些极端的低效率,但我不确定我在哪里出了差错,因为我对这种制度和工作方式还不熟悉

感谢所有能就此提供建议或指导的人

编辑

下面是一个示例,说明了什么是
report
,以及函数返回的结果

这是我自己写的一句话,因此,不是从任何真实的记录中提取出来的

report = 'The patient showed up to the hospital, presenting with a heart attack and diabetes'

   \\ code

return ['heart attack, diabetes','myocardial infarction, diabetes mellatus', 'X88989,B898232']


其中第一项是句子中由代码标记的任何实际字符串,第二项是专业医疗等效项,第三项只是帮助我们找到其他代码之间诊断层次的代码,如果您只有4个拼花文件输出,则表示您的分区太小,在写之前尝试重新分区。例如:

output_frame= output_frame.repartition(500)
output_frame.write.parquet(data_bucket)

如果您只有4个拼花文件输出,也就是说您的分区太小,请在写入之前尝试重新分区。例如:

output_frame= output_frame.repartition(500)
output_frame.write.parquet(data_bucket)

您是如何创建列表的,数据的实际来源是什么。你能用一些虚构的数据作为例子来演示吗。这将真正有助于理解这个问题。谢谢如果您只写4个输出文件,那么您可能只使用4个内核,而不是全部30个。你可以在斯巴库里查一下。这场演出是花3个小时还是用拼花地板?由于执行迟缓,您实际上正在计算一些事情twice@Paul,对于最初的3小时试验,我只显示数据帧。我假设延迟执行会在演出期间调用一次udf函数,然后在我们开始编写时设置数据集。你是说它将在show中执行一次,然后在write中执行一次?@vikrantrana我刚刚编辑了这篇文章,以提供一个更好的例子,说明输入和输出看起来像什么。show可能不会导致完全计算,而只是在一些分区s.t上计算。可以显示请求的20行。这可能解释了创建列表的方式和数据的实际来源之间的差异。你能用一些虚构的数据作为例子来演示吗。这将真正有助于理解这个问题。谢谢如果您只写4个输出文件,那么您可能只使用4个内核,而不是全部30个。你可以在斯巴库里查一下。这场演出是花3个小时还是用拼花地板?由于执行迟缓,您实际上正在计算一些事情twice@Paul,对于最初的3小时试验,我只显示数据帧。我假设延迟执行会在演出期间调用一次udf函数,然后在我们开始编写时设置数据集。你是说它将在show中执行一次,然后在write中执行一次?@vikrantrana我刚刚编辑了这篇文章,以提供一个更好的例子,说明输入和输出看起来像什么。show可能不会导致完全计算,而只是在一些分区s.t上计算。可以显示请求的20行。这或许可以解释这种差异