在 spark scala 中处理十进制值

Posted

技术标签:

【中文标题】在 spark scala 中处理十进制值【英文标题】:Handling decimal values in spark scala 【发布时间】:2018-05-31 07:31:18 【问题描述】:

我在一个文件中有如下所示的数据:

7373743343333444.
7373743343333432.

此数据应转换为十进制值,并应位于 8.7 的位置,其中 8 是小数点前的数字,7 是小数点后的数字。 我正在尝试读取数据文件如下:

val readDataFile = Initialize.spark.read.format("com.databricks.spark.csv").option("header", "true").option("delimiter", "|").schema(***SCHEMA*****).load(****DATA FILE PATH******)

我试过这个:

val changed = dataFileWithSchema.withColumn("COLUMN NAME", dataFileWithSchema.col("COLUMN NAME").cast(new DecimalType(38,3)))
println(changed.show(5))

但它只会在数字的末尾给我零,就像这样:

7373743343333444.0000

但我想要按照上述格式设置的数字,我该如何实现呢?

【问题讨论】:

有什么问题 - 你的号码7373743343333444.7373743343333444.0000一样? 示例中有 16 个字符长的数字,但希望它是 8.7,是否应该删除最后一个数字? 【参考方案1】:

regexp_replacetrimformat_number 内置函数的简单组合应该可以满足您的需求

import org.apache.spark.sql.functions._
df.withColumn("column", regexp_replace(format_number(trim(regexp_replace(col("column"), "\\.", "")).cast("long")/100000000, 7), ",", ""))

【讨论】:

【参考方案2】:

将列除以10^8,这会将小数点移动 8 步。之后转换为DecimalType 以获得正确的小数位数。由于开头有 16 位数字,这意味着最后一位被删除。

df.withColumn("col", (col("col").cast(DoubleType)/math.pow(10,8)).cast(DecimalType(38,7)))

【讨论】:

以上是关于在 spark scala 中处理十进制值的主要内容,如果未能解决你的问题,请参考以下文章

十进制数据类型无法在 spark 和 Hive 中正确存储值

大负十进制值在带有十进制类型的spark DataFrame中取整

在 Spark Structured Streaming 中处理二进制数据

Java/scala BigDecimal 解析 128 位十六进制值

Scala 2.10 - 八进制转义已被弃用 - 现在如何惯用八进制?

Spark Java 将数据帧中的每个值四舍五入到小数点后两位。