Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark PySpark中基于Spark数据帧的for循环中的列操作优化_Apache Spark_Pyspark_Apache Spark Sql_Amazon Emr - Fatal编程技术网

Apache spark PySpark中基于Spark数据帧的for循环中的列操作优化

Apache spark PySpark中基于Spark数据帧的for循环中的列操作优化,apache-spark,pyspark,apache-spark-sql,amazon-emr,Apache Spark,Pyspark,Apache Spark Sql,Amazon Emr,我试图在Spark数据帧(df_qc)的每一列(=定量连续变量)上应用相同的一组(18左右)变换,以生成建模练习的新特征 初始数据帧df_qc有大约700k行和180列 我在df_qc的所有列上运行for循环,在每一轮中使用.withColumn()函数扩展df_qc。在应用给定列的所有转换之后,我缓存扩展数据帧 我在每10列之后对数据帧进行localCheckpoint(以中断沿袭,否则由于沿袭太大而进入OOM) 我正在记录执行这些操作所需的时间,我注意到,随着我添加越来越多的列,执行18组转

我试图在Spark数据帧(df_qc)的每一列(=定量连续变量)上应用相同的一组(18左右)变换,以生成建模练习的新特征

初始数据帧df_qc有大约700k行和180列

我在df_qc的所有列上运行for循环,在每一轮中使用.withColumn()函数扩展df_qc。在应用给定列的所有转换之后,我缓存扩展数据帧

我在每10列之后对数据帧进行localCheckpoint(以中断沿袭,否则由于沿袭太大而进入OOM)

我正在记录执行这些操作所需的时间,我注意到,随着我添加越来越多的列,执行18组转换所需的时间正在增加。这可能是由于df本身的大小不断增大,但我对此表示怀疑,因为这个df仍然相对较小

我正在使用pysparkapi。我在一个有4个节点的EMR集群上运行,工作节点是m4.xlarge机器

(1) 我尝试了多种不同的设置:

  • 没有LocalCheckpoint=>导致由于数据沿袭而导致内存中断
  • 对于10列(耗时10分钟)、20列(耗时16分钟)、40列(耗时1小时24分钟)的LocalCheckpoint=>这种时间上的“指数”增长让我感到不舒服
在查看阶段时,我发现LocalCheckpoint是瓶颈。

即使没有它我也做不到。。。 我希望实现一种状态,在这种状态下,我可以在大致恒定的时间内为每个列运行转换集

这是一个可复制的代码: (在现实生活中,我希望使用nids=100k和nqsc=200运行)

从集合导入defaultdict
导入pyspark.sql.F函数
从pyspark.sql.window导入窗口
将numpy作为np导入
作为pd进口熊猫
从pyspark.sql.types导入datetime、DoubleType、FloatType、IntegerType
进口itertools
#创建虚拟输入数据
n月数=12#不同日期数
nids=1000#不同ID的数量
nqcs=5#列数
id=list()
对于范围内的i(1,nids+1):
id=id+list(itertools.repeat(i,nmonths))
dummyData={'ID':ID
,'DATE':nids*[*范围(1,n个月+1)]n
对于范围内的i(1,nqcs):
dummyData['QC_'+str(i)]=np.random.uniform(大小=nmonths*nids)
pdDF=pd.DataFrame(dummyData)
df_qc=spark.createDataFrame(pdDF)
#df_qc.show()
#添加转换
w=Window.partitionBy('ID'))\
.orderBy(“日期”)
计数器=1
start=datetime.datetime.now()
对于df_质控列中的列[2:]:
#1)生成窗口转换
start_in_loop=datetime.datetime.now()
df_qc=df_qc.带列(列+列1',F.lag(df_qc[col],计数=1).超过(w))\
.带列(列+列2',F.滞后(df_qc[col],计数=2)。超过(w))\
.带列(列+列3',F.滞后(df_qc[col],计数=3)。超过(w))\
.带列(列+列4',F.滞后(df_qc[col],计数=4)。超过(w))\
.带列(列+列5',F.滞后(df_qc[col],计数=5)。超过(w))\
.带列(列+列6',F.滞后(df_qc[col],计数=6)。超过(w))\
.带列('QC_DMAX'+col[2:],df_QC[col]-F.max(df_QC[col])。在(w)上方)\
带列('QC_-DMIN'+col[2:],df_-QC[col]-F.min(df_-QC[col])。在(w)上方)\
带列('QC_-DAVG'+col[2:],df_-QC[col]-F.avg(df_-QC[col])。在(w)上方)\
.cache()
df_qc=df_qc.带列('qc_AD'+列[2:][+''u 1',df_qc[col]-df_qc[col+'u 1'])\
.带列('QC_AD'+列[2::][+''u 3',df_QC[col]-df_QC[col+'u 3'])\
.带列('QC_AD'+列[2::][+''u 6',df_QC[col]-df_QC[col+'u 6'])\
。带列('QC_-RD'+列[2::][1],(df_-QC[col]-df_-QC[col+'-1'))/df_-QC[col+'-1'))\
.带列('QC_-RD'+列[2::][3],(df_-QC[col]--df_-QC[col+[u3'])/df_-QC[col+[u3']))\
.带列('QC_-RD'+列[2:][+''u-6',(df_-QC[col]-df_-QC[col+'u-6'])/df_-QC[col+'u-6']))\
.带列('QC_-MA'+列[2:][+''u-1',(df_-QC[col]+df_-QC[col+'u-1'])/2)\
.带列('QC_-MA'+列[2:]+''u-2',(df_-QC[col]+df_-QC[col+'u-1']+df_-QC[col+'u-2'])/3)\
.带列('QC_-MA'+列[2:][+''u-3',(df_-QC[col]+df_-QC[col+''u-1']+df_-QC[col+'u-2']+df_-QC[col+'u-3'])/4)\
.cache()
#localcheckpointing(用于中断沿袭)
如果计数器%10==0:
start\u checkpoint=datetime.datetime.now()
df_qc=df_qc.localCheckpoint()
打印('-Time-speed-checkpoint::'+str(datetime.datetime.now()-start\u checkpoint))
计数器+=1
打印(“-Generating window tansformation”|“+col+”::“+str(datetime.datetime.now()-start_in_loop))
打印(“=>总运行时间窗口聚合::”+str(datetime.datetime.now()-start))
有什么想法我做错了什么,或者如何优化这种类型的代码吗


非常感谢

您使用的方法不是在Spark中实现的好方法。用这种方式,Spark必须读取每个数据并将其保存在内存中,或者必须在某处写入,否则我认为它不会执行任何操作。我曾经遇到过类似的问题,并通过加入dataframe解决了它。请提供输入数据帧、转换数据帧/dict的详细信息,以及预期输出的内容,以及是否存在任何暂存数据帧。亲爱的@Nikk,谢谢您的回复。好的,我将准备一个小的可复制的例子,并张贴在这里。请注意,我也尝试过加入,但在我看来,这并不是一个有效的方式,因为洗牌。我想避免混乱,这就是我为什么选择.withColumns()@Nikk,我添加了一段可复制的代码。在我的实际情况中,我希望使用nids 100k和nqcs=200运行。我想得到a的一个版本,在这个版本中,时间随着n的数目线性增加得更少