Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.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
Scala 如何使用一个列表(1000个条目)高效地生成一个Spark数据帧(100万行)笛卡尔积,从而生成一个包含10亿行的新数据帧_Scala_Apache Spark_Dataframe_Rdd - Fatal编程技术网

Scala 如何使用一个列表(1000个条目)高效地生成一个Spark数据帧(100万行)笛卡尔积,从而生成一个包含10亿行的新数据帧

Scala 如何使用一个列表(1000个条目)高效地生成一个Spark数据帧(100万行)笛卡尔积,从而生成一个包含10亿行的新数据帧,scala,apache-spark,dataframe,rdd,Scala,Apache Spark,Dataframe,Rdd,我想获取一个数据帧的每一行,它有100万行,并从每一行生成1000行,方法是获取一个具有1000个条目的列表的叉积,从而生成一个具有10亿行的数据帧。有效地做这件事的最佳方法是什么。 我尝试过广播列表,然后在映射数据帧的每一行时使用它。但这似乎花费了太多时间 val mappedrdd = validationDataFrames.map(x => { val cutoffList : List[String] = cutoffListBroadcast.value

我想获取一个数据帧的每一行,它有100万行,并从每一行生成1000行,方法是获取一个具有1000个条目的列表的叉积,从而生成一个具有10亿行的数据帧。有效地做这件事的最佳方法是什么。
我尝试过广播列表,然后在映射数据帧的每一行时使用它。但这似乎花费了太多时间

 val mappedrdd = validationDataFrames.map(x => {
     val cutoffList : List[String] = cutoffListBroadcast.value
     val arrayTruthTableVal = arrayTruthTableBroadcast.value

     var listBufferRow: ListBuffer[Row] = new ListBuffer()

       for(cutOff <- cutoffList){
          val conversion = x.get(0).asInstanceOf[Int]
          val probability = x.get(1).asInstanceOf[Double]

          var columnName : StringBuffer = new StringBuffer
          columnName = columnName.append(conversion)

          if(probability > cutOff.toDouble){
              columnName = columnName.append("_").append("1")
          }else{
              columnName = columnName.append("_").append("0")
          }
          val index:Int  = arrayTruthTableVal.indexOf(columnName.toString)
          var listBuffer : ListBuffer[String] = new ListBuffer()
          listBuffer :+= cutOff

          for(i <- 1 to 4){
             if((index + 1) == i) listBuffer :+= "1" else listBuffer :+= "0"
          }
          val row = Row.fromSeq(listBuffer)
          listBufferRow = listBufferRow :+ row
        }

      listBufferRow

     })
val-mappedrdd=validationDataFrames.map(x=>{
val截止列表:列表[字符串]=截止列表广播.value
val arrayTruthTableVal=arrayTruthTableBroadcast.value
var listBufferRow:ListBuffer[Row]=新ListBuffer()
用于(截止。toDouble){
columnName=columnName.append(“”).append(“1”)
}否则{
columnName=columnName.append(“”).append(“0”)
}
val index:Int=arrayTruthTableVal.indexOf(columnName.toString)
var listBuffer:listBuffer[String]=new listBuffer()
listBuffer:+=截止

对于(i根据您的spark版本,您可以执行以下操作:

def time[R](block: => R): Long = {
    val t0 = System.currentTimeMillis()
    block    // call-by-name
    val t1 = System.currentTimeMillis()
    t1 - t0
 }
  time(spark.range(1000000).withColumn("a",lit((0 until 1000).toArray)).withColumn("a", explode($"a")).count())
Spark 2.1.0

将列表添加为列并分解。一个简化示例:

val df = spark.range(5)
val exploded = df.withColumn("a",lit(List(1,2,3).toArray)).withColumn("a", explode($"a"))
df.show()

+---+---+
| id|  a|
+---+---+
|  0|  1|
|  0|  2|
|  0|  3|
|  1|  1|
|  1|  2|
|  1|  3|
|  2|  1|
|  2|  2|
|  2|  3|
|  3|  1|
|  3|  2|
|  3|  3|
|  4|  1|
|  4|  2|
|  4|  3|
+---+---+
对于计时,您可以执行以下操作:

def time[R](block: => R): Long = {
    val t0 = System.currentTimeMillis()
    block    // call-by-name
    val t1 = System.currentTimeMillis()
    t1 - t0
 }
  time(spark.range(1000000).withColumn("a",lit((0 until 1000).toArray)).withColumn("a", explode($"a")).count())
在一台16核计算机上花费了5.41秒,该计算机有大量内存,默认并行度为60

您可以定义一个简单的UDF

 val xx = (0 until 1000).toArray.toSeq // replace with your list but turn it to seq
  val ff = udf(() => {xx})
  time(spark.range(1000000).withColumn("a",ff()).withColumn("a", explode($"a")).count())

在8.25秒以上的同一台服务器上运行

您考虑过使用数据集吗?您将从内置优化中获益,您可以对两个表应用交叉连接“但这似乎花费了太多时间。”它需要多长时间,您预计需要多长时间?生成10亿行将是非常昂贵的。实际上它永远不会完成。它会被困在listBufferRow=listBufferRow:+row执行器的线程转储时,我可以看到被困在listBufferRow=listBufferRow:+row的线程在r上也可以正常工作兴高采烈的小DF。