【问题标题】:build a 2D lookup table from Spark Dataframe从 Spark Dataframe 构建 2D 查找表
【发布时间】:2017-09-11 23:20:54
【问题描述】:

我想将较小的数据帧转换为广播查找表,以便在另一个较大数据帧的 UDF 中使用。这个较小的数据框 (myLookupDf) 可能如下所示:

+---+---+---+---+
| x | 90|100|101|
+---+---+---+---+
| 90|  1|  0|  0|
|100|  0|  1|  1|
|101|  0|  1|  1|
+---+---+---+---+

我想使用第一列作为第一个键,比如 x1,第一行作为第二个键。 x1 和 x2 具有相同的元素。理想情况下,查找表 (myLookupMap) 将是一个 Scala 映射(或类似的)并且工作方式如下:

myLookupMap(90)(90) returns 1
myLookupMap(90)(101) returns 0
myLookupMap(100)(90) returns 0
myLookupMap(101)(100) return 1
etc.

到目前为止,我设法拥有:

val myLookupMap = myLookupDf.collect().map(r => Map(myLookupDf.columns.zip(r.toSeq):_*))
myLookupMap: Array[scala.collection.Map[String,Any]] = Array(Map(x -> 90, 90 -> 1, 100 -> 0, 101 -> 0), Map(x -> 100, 90 -> 0, 100 -> 1, 101 -> 1), Map(x -> 101, 90 -> 0, 100 -> 1, 101 -> 1))

这是一个 Map 数组,并不完全是所需的。任何建议都非常感谢。

【问题讨论】:

  • 为什么要将数据框转换为地图?以及您想如何将广播的 df 用于另一个 df?
  • 由于 UDF 使用查找表,它不能是数据框。这种方法用于避免两个数据帧的笛卡尔连接,因为较大的数据帧可能很大。
  • 我根据您的解释所理解的回答如下:)希望答案对您有所帮助

标签: scala apache-spark dataframe broadcast lookup-tables


【解决方案1】:

collect() 总是创建rdd,它等价于Array。你必须想办法将arrays 收集为maps。

鉴于dataframe为

scala> myLookupDf.show(false)
+---+---+---+---+
|x  |90 |100|101|
+---+---+---+---+
|90 |1  |0  |0  |
|100|0  |1  |1  |
|101|0  |1  |1  |
+---+---+---+---+

您只需要x 以外的标题名称,因此您可以执行以下操作

scala>     val header = myLookupDf.schema.fieldNames.tail
header: Array[String] = Array(90, 100, 101)

我只是在修改您的 map 函数以获得 Map 作为结果

scala>     val myLookupMap = myLookupDf.rdd.map(r => {
     |       val row = r.toSeq
     |       (row.head, Map(header.zip(row.tail):_*))
     |     }).collectAsMap()
myLookupMap: scala.collection.Map[Any,scala.collection.immutable.Map[String,Any]] = Map(101 -> Map(90 -> 0, 100 -> 1, 101 -> 1), 100 -> Map(90 -> 0, 100 -> 1, 101 -> 1), 90 -> Map(90 -> 1, 100 -> 0, 101 -> 0))

你应该看到你得到了想要的结果。

scala> myLookupMap(90)(90.toString)
res1: Any = 1

scala> myLookupMap(90)(101.toString)
res2: Any = 0

scala> myLookupMap(100)(90.toString)
res3: Any = 0

scala> myLookupMap(101)(100.toString)
res4: Any = 1

现在您可以将myLookupMap 传递给您的udf 函数

【讨论】:

  • 我很高兴@Jonathan :) 感谢您的接受 :) 当您有资格时,您也可以投票 :)
猜你喜欢
  • 2019-07-08
  • 2020-01-31
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 2020-08-09
相关资源
最近更新 更多