数据框上的平面图
Flatmap on dataframe
在 spark 中对 DataFrame
执行 flatMap
的最佳方法是什么?
通过四处搜索和做一些测试,我想出了两种不同的方法。这两者都有一些缺点,所以我认为应该有一些 better/easier 方法来做到这一点。
我找到的第一种方法是先将 DataFrame
转换为 RDD
然后再转换回来:
val map = Map("a" -> List("c","d","e"), "b" -> List("f","g","h"))
val df = List(("a", 1.0), ("b", 2.0)).toDF("x", "y")
val rdd = df.rdd.flatMap{ row =>
val x = row.getAs[String]("x")
val x = row.getAs[Double]("y")
for(v <- map(x)) yield Row(v,y)
}
val df2 = spark.createDataFrame(rdd, df.schema)
第二种方法是在使用flatMap
之前创建一个DataSet
(使用与上面相同的变量)然后转换回来:
val ds = df.as[(String, Double)].flatMap{
case (x, y) => for(v <- map(x)) yield (v,y)
}.toDF("x", "y")
当列数较少时,这两种方法都能很好地工作,但我的列数远远超过 2 列。有没有更好的方法来解决这个问题?最好是不需要转换的方式。
您可以从 map
RDD 创建第二个 dataframe
:
val mapDF = Map("a" -> List("c","d","e"), "b" -> List("f","g","h")).toList.toDF("key", "value")
然后执行 join
并应用 explode
函数:
val joinedDF = df.join(mapDF, df("x") === mapDF("key"), "inner")
.select("value", "y")
.withColumn("value", explode($"value"))
你得到了解决方案。
joinedDF.show()
在 spark 中对 DataFrame
执行 flatMap
的最佳方法是什么?
通过四处搜索和做一些测试,我想出了两种不同的方法。这两者都有一些缺点,所以我认为应该有一些 better/easier 方法来做到这一点。
我找到的第一种方法是先将 DataFrame
转换为 RDD
然后再转换回来:
val map = Map("a" -> List("c","d","e"), "b" -> List("f","g","h"))
val df = List(("a", 1.0), ("b", 2.0)).toDF("x", "y")
val rdd = df.rdd.flatMap{ row =>
val x = row.getAs[String]("x")
val x = row.getAs[Double]("y")
for(v <- map(x)) yield Row(v,y)
}
val df2 = spark.createDataFrame(rdd, df.schema)
第二种方法是在使用flatMap
之前创建一个DataSet
(使用与上面相同的变量)然后转换回来:
val ds = df.as[(String, Double)].flatMap{
case (x, y) => for(v <- map(x)) yield (v,y)
}.toDF("x", "y")
当列数较少时,这两种方法都能很好地工作,但我的列数远远超过 2 列。有没有更好的方法来解决这个问题?最好是不需要转换的方式。
您可以从 map
RDD 创建第二个 dataframe
:
val mapDF = Map("a" -> List("c","d","e"), "b" -> List("f","g","h")).toList.toDF("key", "value")
然后执行 join
并应用 explode
函数:
val joinedDF = df.join(mapDF, df("x") === mapDF("key"), "inner")
.select("value", "y")
.withColumn("value", explode($"value"))
你得到了解决方案。
joinedDF.show()