Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.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 Explode函数增加了Spark数据帧中的作业时间_Scala_Dataframe_Apache Spark_Dataset - Fatal编程技术网

Scala Explode函数增加了Spark数据帧中的作业时间

Scala Explode函数增加了Spark数据帧中的作业时间,scala,dataframe,apache-spark,dataset,Scala,Dataframe,Apache Spark,Dataset,我有一个数据帧,其中一列arr的数组大小接近100000。 现在我需要分解此列,以获得数组中所有元素的唯一行 spark.sql的Explode函数正在执行此任务,但需要足够的时间 任何爆炸的选择,我可以尝试优化工作 dfs.printSchema() println("Orginal DF") dfs.show() //Performing Explode operation import org.apache.spark.sql.functions.{explode,col}

我有一个数据帧,其中一列arr的数组大小接近100000。 现在我需要分解此列,以获得数组中所有元素的唯一行

spark.sql的Explode函数正在执行此任务,但需要足够的时间 任何爆炸的选择,我可以尝试优化工作

 dfs.printSchema()
 println("Orginal DF")
 dfs.show()

 //Performing Explode operation
 import org.apache.spark.sql.functions.{explode,col}
 val opdfs=dfs.withColumn("explarrs",explode(col("arrs"))).drop("arrs")
 println("Exploded DF")
 opdfs.show()
预期结果应如下所示,但这是该代码的替代方案,可更有效地优化作业

原始DF

+----+------+----+--------------------+
|col1|  col2|col3|                arrs|
+----+------+----+--------------------+
|   A|DFtest|   K|[1, 2, 3, 4, 5, 6...|
+----+------+----+--------------------+

Exploded DF
+----+------+----+--------+
|col1|  col2|col3|explarrs|
+----+------+----+--------+
|   A|DFtest|   K|       1|
|   A|DFtest|   K|       2|
|   A|DFtest|   K|       3|
|   A|DFtest|   K|       4|
|   A|DFtest|   K|       5|
|   A|DFtest|   K|       6|
|   A|DFtest|   K|       7|
|   A|DFtest|   K|       8|
|   A|DFtest|   K|       9|
|   A|DFtest|   K|      10|
|   A|DFtest|   K|      11|
|   A|DFtest|   K|      12|
|   A|DFtest|   K|      13|
|   A|DFtest|   K|      14|
|   A|DFtest|   K|      15|
|   A|DFtest|   K|      16|
|   A|DFtest|   K|      17|
|   A|DFtest|   K|      18|
|   A|DFtest|   K|      19|
|   A|DFtest|   K|      20|
+----+------+----+--------+
only showing top 20 rows

您可以使用Dataframe中的flatMap方法执行相同的操作,而无需进行分解。例如,如果需要分解整数数组,可以执行以下操作:

val els = Seq(Row(Array(1, 2, 3)))
val df = spark.createDataFrame(spark.sparkContext.parallelize(els), StructType(Seq(StructField("data", ArrayType(IntegerType), false))))
df.show()
val els = Seq(Row(Array(1, 2, 3), "data1", "data2"), Row(Array(1, 2, 3, 4, 5, 6), "data10", "data20"))

val df = spark.createDataFrame(spark.sparkContext.parallelize(els),
  StructType(Seq(StructField("data", ArrayType(IntegerType), false), StructField("data1", StringType, false), StructField("data2", StringType, false))))

df.show()

df.flatMap{ row =>
  val arr = row.getAs[mutable.WrappedArray[Int]](0)
  arr.map { el =>
    (row.getAs[String](1), row.getAs[String](2), el)
  }
}.show()
它给出:

+---------+
|     data|
+---------+
|[1, 2, 3]|
+---------+
+------+------+---+
|    _1|    _2| _3|
+------+------+---+
| data1| data2|  1|
| data1| data2|  2|
| data1| data2|  3|
|data10|data20|  1|
|data10|data20|  2|
|data10|data20|  3|
|data10|data20|  4|
|data10|data20|  5|
|data10|data20|  6|
+------+------+---+
使用Dataframe的平面图:

df.flatMap(row => row.getAs[mutable.WrappedArray[Int]](0)).show()

+-----+
|value|
+-----+
|    1|
|    2|
|    3|
+-----+
问题在于,除了内存开销之外,还需要在getAs函数中放置正确类型的数组元素。正如我在评论中所说,有一个bug已经修复:

但是如果你不能升级你的Spark版本,你可以尝试上面的代码并进行比较

如果要将其他字段添加到结果中,可以执行以下操作:

val els = Seq(Row(Array(1, 2, 3)))
val df = spark.createDataFrame(spark.sparkContext.parallelize(els), StructType(Seq(StructField("data", ArrayType(IntegerType), false))))
df.show()
val els = Seq(Row(Array(1, 2, 3), "data1", "data2"), Row(Array(1, 2, 3, 4, 5, 6), "data10", "data20"))

val df = spark.createDataFrame(spark.sparkContext.parallelize(els),
  StructType(Seq(StructField("data", ArrayType(IntegerType), false), StructField("data1", StringType, false), StructField("data2", StringType, false))))

df.show()

df.flatMap{ row =>
  val arr = row.getAs[mutable.WrappedArray[Int]](0)
  arr.map { el =>
    (row.getAs[String](1), row.getAs[String](2), el)
  }
}.show()
它给出:

+---------+
|     data|
+---------+
|[1, 2, 3]|
+---------+
+------+------+---+
|    _1|    _2| _3|
+------+------+---+
| data1| data2|  1|
| data1| data2|  2|
| data1| data2|  3|
|data10|data20|  1|
|data10|data20|  2|
|data10|data20|  3|
|data10|data20|  4|
|data10|data20|  5|
|data10|data20|  6|
+------+------+---+

也许会有帮助。

您使用的是哪种版本的Spark?。这是在2.3中修复的,我使用的是Spark 2.1.1,如果我的数据框架中有多个列,如下所示+------+---------+----+----+----col1 | col2 | col3 | arrs |+----+----A | DFtest | K |[1,2,3,4]|++------++--------编辑您的问题并添加一些内容,以便更好地理解。嗨,EmiCareOfCell44--感谢您的回复,我编辑了问题并格式化了内容,以便更好地理解上述三列解决方案正在做我的工作。但是与分解方法相比,它需要更多的时间。这取决于有多少列你的记录。由于explode版本在2.3之前的版本中具有指数级的时间复杂度,如果您的记录数增加,您可以使用具有线性增量的flatMap版本进行实验。