gpt4 book ai didi

scala - 将带有结构类型键的映射传递到 Spark UDF

转载 作者:行者123 更新时间:2023-12-03 03:30:48 24 4
gpt4 key购买 nike

我想编写一个 Spark 1.6 UDF,它采用以下映射:

case class MyRow(mapping: Map[(Int, Int), Double])

val data = Seq(
MyRow(Map((1, 1) -> 1.0))
)
val df = sc.parallelize(data).toDF()

df.printSchema()

root
|-- mapping: map (nullable = true)
| |-- key: struct
| |-- value: double (valueContainsNull = false)
| | |-- _1: integer (nullable = false)
| | |-- _2: integer (nullable = false)

(旁注:我发现上面的输出很奇怪,因为键的类型打印在值的类型下方,这是为什么?)

现在我将我的 UDF 定义为:

val myUDF = udf((inputMapping: Map[(Int,Int), Double]) =>
inputMapping.map { case ((i1, i2), value) => ((i1 + i2), value) }
)

df
.withColumn("udfResult", myUDF($"mapping"))
.show()

但这给了我:

java.lang.ClassCastException: org.apache.spark.sql.catalyst.expressions.GenericRowWithSchema cannot be cast to scala.Tuple2

因此,我尝试将 (Int,Int) 替换为自定义 case 类,因为如果我想传递 ,这就是我通常的做法struct 到 UDF:

case class MyTuple2(i1: Int, i2: Int)
val myUDF = udf((inputMapping: Map[MyTuple2, Double]) =>
inputMapping.map { case (MyTuple2(i1, i2), value) => ((i1 + i2), value) }
)

这奇怪地给出了:

org.apache.spark.sql.AnalysisException: cannot resolve 'UDF(mapping)' due to data type mismatch: argument 1 requires map<struct<i1:int,i2:int>,double> type, however, 'mapping' is of map<struct<_1:int,_2:int>,double> type.

我不明白上述异常,因为类型匹配。

我发现的唯一(丑陋的)解决方案是传递org.apache.spark.sql.Row,然后“提取”结构的元素:

val myUDF = udf((inputMapping: Map[Row, Double]) => inputMapping
.map { case (key, value) => ((key.getInt(0), key.getInt(1)), value) } // extract Row into Tuple2
.map { case ((i1, i2), value) => ((i1 + i2), value) }
)

最佳答案

据我所知,在这种情况下无法避免使用 Row:在映射(或另一个元组/案例类/数组)中使用的元组(或案例类)... ) 是一个嵌套结构,因此在传递到 UDF 时将表示为Row

我可以建议的唯一改进是使用 Row.unapply 来简化代码:

val myUDF = udf((inputMapping: Map[Row, Double]) => inputMapping
.map { case (Row(i1: Int, i2: Int), value) => (i1 + i2, value) }
)

关于scala - 将带有结构类型键的映射传递到 Spark UDF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41806914/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com