火花& Scala:生成给定大小的DataSet(或Dataframe)

时间:2017-01-11 16:12:58

标签: scala apache-spark

出于评估目的,我需要一个创建虚拟函数的函数 - Dataset(或者,DataFrame),用随机数初始化。列和行的尺寸应该是参数化的

我提出了一个解决方案,但这是非常慢的(10列100列的5.3秒):

def createDummyDataset(rows : Int, columns: Int, spark: SparkSession) = {
   import spark.implicits._

   var ds = Seq.fill(rows)(Random.nextDouble).toDF()
   if (columns > 1) {
      for (i <- 2 to columns) {
         ds = ds.withColumn(i.toString, rand)
      }
   }
   ds // return ds
}

这是由于Spark的架构还是我做错了什么并且有更好的方法?

我想更好的方法是定义某种矩阵并将其转换为Dataset。但我无法弄明白。

系统:Spark 2.1.0,Scala 2.11.8,Ubuntu 16.04,i5-6300U,32GB RAM

2 个答案:

答案 0 :(得分:1)

通过向现有DataFrame添加列来实现它会导致很多与Spark相关的开销。

最好创建一个2D数组样式集合,然后将所有内容并行化:

import org.apache.spark.sql.Row
import spark.implicits._

val data = (0 to rows).map(_ => Seq.fill(columns)(Random.nextDouble))
val rdd = sc.parallelize(data)
val df = rdd.map(s => Row.fromSeq(s)).toDF()

答案 1 :(得分:1)

根据ImDarrenG的回答,输出是一个n行m列的数据帧。

import org.apache.spark.sql.{Row, SparkSession}
import org.apache.spark.sql.types.{DoubleType, StructField, StructType}

def start(rows: Int, cols: Int, col: String, spark: SparkSession): Unit = {

         val data = (1 to rows).map(_ => Seq.fill(cols)(Random.nextDouble))

         val colNames = (1 to cols).mkString(",")
         val sch = StructType(colNames.split(",").map(fieldName => StructField(fieldName, DoubleType, true)))

         val rdd = spark.sparkContext.parallelize(data.map(x => Row(x:_*)))
         val df = spark.sqlContext.createDataFrame(rdd, sch)

         df.printSchema()

         spark.stop()
    }

在Spark 2.1.0,Scala 2.11.8,Fedora Scientific,i5-5200U 4核,16Gb RAM上运行

对于10行×100列,平均经过时间为0.9秒