You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark读取高标度零值decimal转科学计数法,如何按原格式写入CSV?

解决方案

针对Spark 2.4.8中Decimal类型零值写入CSV时自动转为科学计数法的问题,可通过动态识别Schema并格式化Decimal字段的方式解决,完全适配通用型应用场景:

核心思路

  1. 自动遍历输入DataFrame的Schema,识别所有DecimalType字段及其对应的标度(scale)
  2. 对每个Decimal字段,根据其scale值格式化为固定小数位数的字符串,同时去除千分位分隔符
  3. 将格式化后的DataFrame写入CSV,此时字符串类型的数值不会触发科学计数法转换

代码实现(Scala)

import org.apache.spark.sql.types.DecimalType
import org.apache.spark.sql.functions._

// 1. 提取所有Decimal类型字段的名称与对应scale
val decimalFieldInfo = df.schema.fields
  .filter(_.dataType.isInstanceOf[DecimalType])
  .map(field => {
    val decimalType = field.dataType.asInstanceOf[DecimalType]
    (field.name, decimalType.scale)
  })

// 2. 批量格式化Decimal字段:转为指定小数位的字符串,移除千分位逗号
val formattedDataFrame = decimalFieldInfo.foldLeft(df) { (currentDf, fieldMeta) =>
  val (colName, scale) = fieldMeta
  currentDf.withColumn(
    colName,
    regexp_replace(format_number(col(colName), scale), ",", "")
  )
}

// 3. 写入CSV文件
formattedDataFrame.write
  .option("header", "true")  // 根据需求开启表头
  .mode("overwrite")         // 根据需求设置写入模式
  .csv("/your/output/path")

关键细节说明

  • format_number(col, scale):将Decimal数值格式化为保留scale位小数的字符串,例如0.00000000(scale=8)会被格式化为"0.00000000",但默认会为大数添加千分位逗号
  • regexp_replace(..., ",", ""):移除千分位逗号,避免数值格式异常
  • 动态遍历Schema:无需提前知晓表结构或字段类型,自动适配所有Decimal字段的不同precision和scale
  • 空值处理:若Decimal字段为null,格式化后仍为null,不影响CSV写入结果

内容的提问来源于stack exchange,提问作者bp2010

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:07:07