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 具有大量列的数据帧上的Spark窗口函数_Apache Spark_Spark Dataframe - Fatal编程技术网

Apache spark 具有大量列的数据帧上的Spark窗口函数

Apache spark 具有大量列的数据帧上的Spark窗口函数,apache-spark,spark-dataframe,Apache Spark,Spark Dataframe,我有一个从csv文件读取的ML数据帧。它包含三种类型的列: ID时间戳功能1功能2…功能\u n 其中n是~500(用ML的说法是500个特征)。数据集中的行总数约为1.6亿 由于这是前一次完全联接的结果,因此存在许多未设置值的功能 我的目标是运行一个“fill”函数(fillna样式的表单),在该函数中,每个空的特征值都会根据Id和日期设置为该列以前可用的值 我试图通过以下spark 2.2.1代码实现这一点: val rawDataset = sparkSession.read.optio

我有一个从csv文件读取的ML数据帧。它包含三种类型的列:

ID时间戳功能1功能2…功能\u n

其中n是~500(用ML的说法是500个特征)。数据集中的行总数约为1.6亿

由于这是前一次完全联接的结果,因此存在许多未设置值的功能

我的目标是运行一个“fill”函数(fillna样式的表单),在该函数中,每个空的特征值都会根据Id和日期设置为该列以前可用的值

我试图通过以下spark 2.2.1代码实现这一点:

 val rawDataset = sparkSession.read.option("header", "true").csv(inputLocation)

 val window = Window.partitionBy("ID").orderBy("DATE").rowsBetween(-50000, -1)

 val columns = Array(...) //first 30 columns initially, just to see it working

val rawDataSetFilled = columns.foldLeft(rawDataset) { (originalDF, columnToFill) =>
      originalDF.withColumn(columnToFill, coalesce(col(columnToFill), last(col(columnToFill), ignoreNulls = true).over(window)))
    }
我使用spark 2.2.1在Amazon EMR上的4个m4.1大型实例上运行此作业。并启用动态分配

作业运行超过2小时而未完成

在代码级别,我是否做错了什么?考虑到数据的大小和实例,我假设它应该在合理的时间内完成?我甚至没有尝试过500个专栏,只有30个

查看容器日志,我看到的都是这样的日志:

INFO codegen.CodeGenerator:在166.677493毫秒内生成的代码

INFO execution.ExternalAppendOnlyUnsafeRowArray:已到达溢出 阈值 4096行,切换到 org.apache.spark.util.collection.unsafe.sort.unsafeeExternalSorter

我已尝试将参数spark.sql.windowExec.buffer.spill.threshold设置为更大的值,但没有任何影响。还有其他我应该知道的环境吗?这两行是我在任何容器日志中看到的唯一一行


在Ganglia中,我看到大多数CPU内核在完全使用时达到峰值,但内存使用低于最大可用内存。所有执行器都已分配并正在工作。

我已成功重写了左折逻辑,而无需使用with column调用。显然,对于大量的列,它们的速度可能会非常慢,我也因此得到了stackoverflow错误

我很想知道为什么会有如此巨大的差异,以及查询计划执行的幕后到底发生了什么,这使得对列的重复调用变得如此缓慢

证明非常有用的链接:以及


你看过执行计划了吗?如果您的数据帧没有按ID重新分区,也没有按ID和日期在分区中排序,那么在foldLeft之前会有一个洗牌和排序。这可能是原因吗?另外,是否真的需要限制-50000?也许你应该先尝试一些较小的值,比如-10。很好的解决方案。现在有多快?你可以看到一篇关于这个的很好的博客文章,在那里你也可以得到一个很好的基准。
    var rawDataset = sparkSession.read.option("header", "true").csv(inputLocation)    
    val window = Window.partitionBy("ID").orderBy("DATE").rowsBetween(Window.unboundedPreceding, Window.currentRow)
    rawDataset = rawDataset.select(rawDataset.columns.map(column => coalesce(col(column), last(col(column), ignoreNulls = true).over(window)).alias(column)): _*)
    rawDataset.write.option("header", "true").csv(outputLocation)