Scala UDF 返回“不支持单元类型的架构”
Posted
技术标签:
【中文标题】Scala UDF 返回“不支持单元类型的架构”【英文标题】:Scala UDF returning 'Schema for type Unit is not supported' 【发布时间】:2018-07-02 15:55:45 【问题描述】:我想更改数据框中的列。该列是整数数组。我想替换数组的一个元素,从另一个数组中获取索引并用第三个数组中的元素替换该元素。示例:我有三列 C1、C2、C3 所有三个数组。我想按如下方式替换 C3 中的元素。
C3[C2[i]] = C1[i].
我写了以下UDF:
def UpdateHist = udf((CRF_count: Seq[Long], Day: Seq[String], History: Seq[Int])=> for(i <- 0 to Day.length-1)History.updated(Day(i).toInt-1 , CRF_count(i).toInt))
并执行了这个:
histdate3.withColumn("History2", UpdateHist2(col("CRF_count"), col("Day"), col("History"))).show()
但它返回如下错误:
scala> histdate3.withColumn("History2", UpdateHist2(col("CRF_count"), col("Day"), col("History"))).show()
java.lang.UnsupportedOperationException:不支持 Unit 类型的架构 在 org.apache.spark.sql.catalyst.ScalaReflection$.schemaFor(ScalaReflection.scala:733) 在 org.apache.spark.sql.catalyst.ScalaReflection$.schemaFor(ScalaReflection.scala:671) 在 org.apache.spark.sql.functions$.udf(functions.scala:3100) 在 UpdateHist2(:25) ... 48 省略
我想我正在返回一些不同的类型,即不支持的 View 类型。请帮我解决这个问题。
【问题讨论】:
For 循环不返回任何内容,因此您使用的函数是(Seq[Long], Seq[String], Seq[Int]) => Unit
是的。那我该如何更新数组呢?有没有其他办法?
【参考方案1】:
您的 for
循环返回 Unit
因此错误消息。你可以使用for-yield
来返回值,但是由于Seq
应该是updated
,所以一个简单的foldLeft
会更好:
import org.apache.spark.sql.functions._
val df = Seq(
(Seq(101L, 102L), Seq("1", "2"), Seq(11, 12)),
(Seq(201L, 202L, 203L), Seq("2", "3"), Seq(21, 22, 23))
).toDF("C1", "C2", "C3")
// +---------------+------+------------+
// |C1 |C2 |C3 |
// +---------------+------+------------+
// |[101, 102] |[1, 2]|[11, 12] |
// |[201, 202, 203]|[2, 3]|[21, 22, 23]|
// +---------------+------+------------+
def updateC3 = udf( (c1: Seq[Long], c2: Seq[String], c3: Seq[Int]) =>
c2.foldLeft( c3 ) (acc, i) =>
val idx = i.toInt - 1
acc.updated(idx, c1(idx).toInt)
)
df.withColumn("C3", updateC3($"C1", $"C2", $"C3")).show(false)
// +---------------+------+--------------+
// |C1 |C2 |C3 |
// +---------------+------+--------------+
// |[101, 102] |[1, 2]|[101, 102] |
// |[201, 202, 203]|[2, 3]|[21, 202, 203]|
// +---------------+------+--------------+
【讨论】:
太棒了!谢谢!以上是关于Scala UDF 返回“不支持单元类型的架构”的主要内容,如果未能解决你的问题,请参考以下文章
Spark SQL UDF 使用 df.WithColumn() 返回 scala 不可变映射