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

如何设置Spark CSV输出的数值格式?调整Double类型输出格式

解决Spark CSV输出Double类型数据的格式问题

这个问题我之前也碰到过,Spark默认确实会把大数Double转成科学计数法输出到CSV里,要改成你需要的1000000000000.00这种固定格式,主要有两种实用的办法,我给你详细说说:

方法一:直接在SQL中用格式化函数转换

如果你的数据是通过SQL查询生成的,可以直接用Spark SQL的format_string函数,指定小数位数来格式化Double值,这样输出的就是符合要求的字符串格式:

val t = spark.sql("SELECT format_string('%.2f', cast(1000000000000 as double)) as aNum")
t.write.csv("WXYZ")

这里'%.2f'是格式化模板,%.2f表示保留两位小数的浮点数格式,这样输出的结果就是1000000000000.00,不会出现科学计数法。

注意:如果用format_number函数的话,会自动添加千分位分隔符(比如输出1,000,000,000,000.00),如果你不需要这个分隔符,就用format_string更合适。

方法二:自定义UDF批量处理所有Double列

如果你的DataFrame里有很多Double类型的列,一个个改SQL太麻烦,可以自定义一个UDF(用户自定义函数),批量处理所有Double列:

  1. 首先定义格式化Double的UDF,同时处理可能的null值:
import org.apache.spark.sql.functions._
import org.apache.spark.sql.types.DoubleType

// 定义UDF,处理Double类型,保留两位小数,同时兼容null值
val formatDoubleUdf = udf((num: Option[Double]) => {
  num.map(n => f"$n%.2f").orElse(None)
})
  1. 然后自动识别DataFrame中所有的Double类型列,批量应用UDF替换原列:
// 获取所有Double类型的列名
val doubleColumnNames = df.schema.fields
  .filter(_.dataType == DoubleType)
  .map(_.name)

// 遍历所有Double列,用UDF格式化后替换原列
val formattedDF = doubleColumnNames.foldLeft(df) { (tempDF, colName) =>
  tempDF.withColumn(colName, formatDoubleUdf(col(colName)))
}

// 写入CSV
formattedDF.write.csv("WXYZ")

这样处理后,所有Double列都会被转成保留两位小数的字符串,输出到CSV里就是你想要的格式了。

补充说明

目前Spark的CSV数据源并没有提供全局配置参数来直接设置Double类型的输出格式,所以必须先把Double类型转换为格式化后的字符串,再写入CSV。这种转换不会影响数据的可读性,因为CSV本身就是文本格式,后续读取时如果需要转回数值类型,也可以通过cast函数处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:39:52