我有一个这样的数据帧:
// +---------+-----------+
// | myString| myDouble|
// +---------+-----------+
// |AAA |2.0 |
// |BBB |3.0 |
// |CCC |1.0 |
// +---------+-----------+
并且我想将 UDF 应用到我的数据框以将 myDouble
列乘以 BigDecimal
,然后得到第三列 myBigDecimal
我的 UDF :
val myUDf : UserDefinedFunction = udf((d : Double) => {
(BigDecimal.valueOf(d)*BigDecimal("1.100000000000000000000000000001")).setScale(30)
})
然后我应用我的 UDF :
df.withcolumn("myBigDecimal", myUdf(col("myDouble"))
然后我得到第一行:myBigDecimal = 2.200000000000000000 //expected 2.200000000000000000000000000002
我打印了架构,发现 myBigDecimal 的类型是:DecimalType(38,18)
我该怎么做才能得到预期的结果? (30 位数比例)
我尝试投射:
df.withcolumn("myBigDecimal", myUdf(col("myDouble").cast(DecimalType(38,30)))
但是我得到了相同的结果并且架构仍然是 DecimalType(38,18)
编辑:通过向 UDF 添加返回类型来解决
答案 0 :(得分:1)
您可以定义具有指定返回类型的 UDF:
import org.apache.spark.sql.types._
spark.sql("set spark.sql.legacy.allowUntypedScalaUDF = true")
val myUdf = udf(
(d : Double) => {(BigDecimal.valueOf(d)*BigDecimal("1.100000000000000000000000000001")).setScale(30)},
DecimalType(38,30)
)
val df = spark.sql("select 2.0d as myDouble")
val df2 = df.withColumn("myBigDecimal", myUdf(col("myDouble")))
df2.show(false)
+--------+--------------------------------+
|myDouble|myBigDecimal |
+--------+--------------------------------+
|2.0 |2.200000000000000000000000000002|
+--------+--------------------------------+