Как установить точность и масштаб десятичного возвращаемого типа в Spark UDF? - PullRequest
0 голосов
/ 08 апреля 2020

Вот мой пример кода. Я ожидаю десятичный (16,4) тип возврата от UDF, но он десятичный (38,18).

Есть ли лучшее решение?

Я НЕ ожидаю ответа "cast (цена как десятичное число (16,4))", так как у меня есть некоторые другие бизнес-логики c в моем UDF, отличные от простого литья.

Заранее спасибо.

import scala.util.Try
import org.apache.spark.sql.functions.udf
import org.apache.spark.sql.types.Decimal
val spark = SparkSession.builder().master("local[*]").appName("Test").getOrCreate()
import spark.implicits._

val stringToDecimal = udf((s:String, precision:Int, scale: Int) => {
  Try(Decimal(BigDecimal(s), precision, scale)).toOption
})

spark.udf.register("stringToDecimal", stringToDecimal)

val inDf = Seq(
  ("1", "864.412"),
  ("2", "1.600"),
  ("3", "2,56")).toDF("id", "price")

val outDf = inDf.selectExpr("id", "stringToDecimal(price, 16, 4) as price")
outDf.printSchema()
outDf.show()

------------------output----------------
root
  |-- id: string (nullable = true)
  |-- price: decimal(38,18) (nullable = true)

+---+--------------------+
| id|               price|
+---+--------------------+
|  1|864.4120000000000...|
|  2|1.600000000000000000|
|  3|                null|
+---+--------------------+

1 Ответ

1 голос
/ 08 апреля 2020

Spark ассоциируется Decimal с decimal(38, 18). Вам нужно явное приведение

$"price".cast(DataTypes.createDecimalType(32,2))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...