Spark CSV writer 为空字符串输出双引号

Bam*_*ylo 2 scala user-defined-functions apache-spark

我为 Scala Spark 编写了 UDF

import org.apache.spark.sql.functions.{col, udf}
def mapToString: Map[String, Double] => String = /** // returns k1:v1,k2:v2 or empty string if map is empty */

val mapToStringUDF = udf(mapToString)

// Then I try to save my Dataset as csv
      myDataset
      .withColumn("map_str", mapToStringUDF(col("map")))
      .drop("map")
      .write
      .option("header", false)
      .option("delimiter", "\t")
      .csv("output.csv")
Run Code Online (Sandbox Code Playgroud)

""如果mapToStringUDF返回空字符串,则输出。如果返回空字符串,我不想在输出中得到任何内容mapToStringUDF

正确的做法是什么?

小智 7

Spark DataFrameWriter 有两个.csv可以设置的格式选项参数:nullValueemptyValue,您都可以将其设置为 ,null而不是空字符串。请参阅此处的DataFrameWriter 文档。

在您的具体示例中,您只需将选项添加到您的write语句中即可:

myDataset
  .withColumn("map_str", mapToStringUDF(col("map")))
  .drop("map")
  .write
  .option("emptyValue", null)
  .option("nullValue", null)
  .option("header", "false")
  .option("delimiter", "\t")
  .csv("output.csv")
Run Code Online (Sandbox Code Playgroud)

或者这是一个完整的示例,包括测试数据:

import org.apache.spark.sql.Row
import org.apache.spark.sql.types._

val data = Seq(
  Row(null, "20200506", "Hello"),
  Row(2, "20200607", null),
  Row(3, null, "World")
  )

val schema = List(
  StructField("Item", IntegerType, true),
  StructField("Date", StringType, true),
  StructField("Message", StringType, true)
  )

val testDF = spark.createDataFrame(
  spark.sparkContext.parallelize(data),
  StructType(schema)
  )

testDF.write
  .option("emptyValue", null)
  .option("nullValue", null)
  .option("header", "true")
  .csv(PATH)
Run Code Online (Sandbox Code Playgroud)

生成的原始结果.csv应如下所示:

Item,Date,Message
,20151231,Hello
2,20160101,
3,,World
Run Code Online (Sandbox Code Playgroud)