Performance 在ApacheSpark中使用统计方法完成表时,如何提高性能?

Performance 在ApacheSpark中使用统计方法完成表时,如何提高性能?,performance,scala,apache-spark,Performance,Scala,Apache Spark,我有一个包含10个字段和5000行的数据集。我想用Spark和Scala中的一些统计方法来完成这个数据集。如果一个字段由连续值组成,我用该字段的平均值填充该字段中的空单元格,如果它由离散值组成,我将最频繁的值放入该字段中。这是我的密码: for(col <- cols){ val datacount = table.select(col).rdd.map(r => r(0)).filter(_ == null).count() if(datacount >

我有一个包含10个字段和5000行的数据集。我想用Spark和Scala中的一些统计方法来完成这个数据集。如果一个字段由连续值组成,我用该字段的平均值填充该字段中的空单元格,如果它由离散值组成,我将最频繁的值放入该字段中。这是我的密码:

for(col <- cols){

  val datacount = table.select(col).rdd.map(r => r(0)).filter(_ == null).count()      

  if(datacount > 0)
  {      
    if (continuous_lst contains col)               // put mean of data to null values
    {             
      var avg = table.select(mean(col)).first()(0).asInstanceOf[Double]    
      df = df.na.fill(avg, Seq(col))             
    }

    else if(discrete_lst contains col)            // put most frequent categorical value to null values
    {
      val group_df = df.groupBy(col).count()  
      val sorted = group_df.orderBy(desc("count")).take(1)

      val most_frequent = sorted.map(t => t(0))
      val most_frequent_ = most_frequent(0).toString.toDouble.toInt

      val type__ = ctype.filter(t => t._1 == col)
      val type_ = type__.map(t => t._2)

      df = df.na.fill(most_frequent_, Seq(col))  
      }

    }
  }
for(colr(0)).filter(==null).count()
如果(数据计数>0)
{      
if(continuous_lst contains col)//将数据的平均值设置为空值
{             
var avg=table.select(mean(col)).first()(0).asInstanceOf[Double]
df=df.na.填充(平均值,序号(列))
}
else if(discrete_lst contains col)//将最频繁的分类值设置为空值
{
val group_df=df.groupBy(col.count)()
val sorted=group_df.orderBy(desc(“count”)).take(1)
val most_frequency=sorted.map(t=>t(0))
val most\u frequency=most\u frequency(0)。toString.toDouble.toInt
val type\uu=ctype.filter(t=>t.\u1==col)
val类型=类型映射(t=>t.\u2)
df=df.na.填充(最频繁,顺序(列))
}
}
}
问题是这段代码处理这些数据的速度非常慢。我使用
spark submit
executor memory 8G
参数。在将数据发送到此函数之前,我使用了repartition(4)参数

我应该处理更大的数据集。那么我怎样才能加速这个代码呢

谢谢你的帮助。

这里有一个建议:

import org.apache.spark.sql.funcitons._

def most_frequent(df: DataFrame, col: Column) = {
  df.select(col).map { case Row(colVal) => (colVal, 1)  } 
    .reduceByKey(_ + _)
    .reduce({case ((val1, cnt1), (val2, cnt2)) => if (cnt1 > cnt2) (val1, cnt1) else (val2, cnt2)})._1
}

val new_continuous_cols = continuous_lst.map {
  col => coalesce(col, mean(col)).as(col.toString)
}.toArray

val new_discrete_cols = discrete_lst.map {
  col => coalesce(col, lit(most_frequent(table, col)).as(col.toString))
}.toArray

val all_new_cols = new_continuous_cols ++ new_discrete_cols
val newDF = table.select(all_new_cols: _*)
注意事项:

  • 我假设
    continuous_lst
    discrete_lst
    列的列表。如果它们是
    字符串的列表
    则想法相同,但需要进行一些调整
  • 请注意,我使用了
    map
    reduce
    来计算列的最频繁值。在某些情况下,这可能比分组和聚合要好。(通过一次计算所有离散列的最频繁值,这里可能有改进的余地?)
  • 此外,我使用了
    coalesce
    替换空值,而不是
    fill
    。这也可能导致一些改进。(有关中的
    合并
    功能的更多信息)
  • 我现在无法测试,所以可能缺少一些我没有看到的东西