在火花中查找表



我有一个在Spark中的数据框架,没有明确定义的架构,我想用作查找表。例如,以下数据框架:

+------------------------------------------------------------------------+
|lookupcolumn                                                            |
+------------------------------------------------------------------------+
|[val1,val2,val3,val4,val5,val6]                                         |
+------------------------------------------------------------------------+

模式看起来像这样:

 |-- lookupcolumn: struct (nullable = true)
 |    |-- key1: string (nullable = true)
 |    |-- key2: string (nullable = true)
 |    |-- key3: string (nullable = true)
 |    |-- key4: string (nullable = true)
 |    |-- key5: string (nullable = true)
 |    |-- key6: string (nullable = true)

我说的是"架构未明确定义",因为读取数据时键的数量未知,所以我留下来推断架构。

现在,如果我有另一个带有以下列的数据框架:

+-----------------+
|       datacolumn|
+-----------------+
|         key1    |
|         key3    |
|         key5    |
|         key2    |
|         key4    |
+-----------------+

我希望结果为:

+-----------------+
|     resultcolumn|
+-----------------+
|         val1    |
|         val3    |
|         val5    |
|         val2    |
|         val4    |
+-----------------+

我尝试过这样的UDF

val get_val = udf((keyindex: String) => {
    val res = lookupDf.select($"lookupcolumn"(keyindex).alias("result"))
    res.head.toString
})

但它引发了无效的指针异常错误。

有人可以告诉我UDF有什么问题,如果有更好/更简单的方法在Spark中进行查找?

我假设查找表很小,在这种情况下,将其收集到驱动程序并将其转换为普通Map是更有意义的。然后在UDF函数中使用此Map。可以以多种方式完成,例如:

val values = lookupDf.select("lookupcolumn.*").head.toSeq.map(_.toString)
val keys = lookupDf.select("lookupcolumn.*").columns
val lookup_map = keys.zip(values).toMap

使用上述lookup_map变量,UDF将仅为:

val lookup = udf((key: String) => lookup_map.get(key))

可以通过:

获得最终数据框架
val df2 = df.withColumn("resultcolumn", lookup($"datacolumn"))

相关内容

  • 没有找到相关文章