Spark Scala中仅替换列Null值而非字符串null的实现问询
解决Spark DataFrame中仅替换Null缺失值而非字符串"null"的问题
我来帮你搞定这个问题~你当前的代码用regexp_replace替换了字符串里所有的"null"子串,这才导致像annullment这类包含"null"的正常单词被误改。要只处理真正的Null缺失值(Spark里的null,不是字符串"null"),可以用以下两种更合适的方法:
方法一:用coalesce直接替换Null值
coalesce函数会返回传入参数中的第一个非Null值,刚好可以用来把Null缺失值替换成空字符串,完全不会影响正常的字符串内容:
import org.apache.spark.sql.functions.{coalesce, lit, col} // 替换concatenated列的Null值为空字符串,再重命名列 val dfMainOutputFinalWithoutNull = dfMainOutputFinal .withColumn("concatenated", coalesce(col("concatenated"), lit(""))) .withColumnRenamed("concatenated", header) // 后续写出逻辑保持不变 dfMainOutputFinalWithoutNull.repartition(1).write.partitionBy("DataPartition","StatementTypeCode") .format("csv") .option("nullValue", "") .option("delimiter", "\t") .option("quote", "\u0000") .option("header", "true") .option("codec", "gzip") .save("s3://trfsmallfffile/FinancialLineItem/output")
方法二:利用写出时的nullValue参数(更简洁)
你其实已经在写出CSV时设置了option("nullValue", ""),这个参数的作用就是:将DataFrame中的所有Null缺失值在写出为CSV时自动转换为空字符串。如果你的concatenated列里的"null"是真正的Spark缺失值,那完全不需要提前做regexp_replace操作,直接写出即可,这样既简洁又不会误改字符串内容:
// 直接重命名列,不需要提前替换 val dfMainOutputFinalRenamed = dfMainOutputFinal .withColumnRenamed("concatenated", header) // 写出时通过nullValue参数自动转换Null值为空字符串 dfMainOutputFinalRenamed.repartition(1).write.partitionBy("DataPartition","StatementTypeCode") .format("csv") .option("nullValue", "") .option("delimiter", "\t") .option("quote", "\u0000") .option("header", "true") .option("codec", "gzip") .save("s3://trfsmallfffile/FinancialLineItem/output")
特殊情况:如果数据中是字符串"null"而非缺失值
如果你的数据里存在的是字符串类型的"null"(比如用户手动输入的"null"文本),而不是Spark的Null缺失值,那可以用when条件判断来精准替换:
import org.apache.spark.sql.functions.{when, col, lit} val dfMainOutputFinalWithoutNull = dfMainOutputFinal .withColumn("concatenated", when(col("concatenated") === "null", lit("")).otherwise(col("concatenated"))) .withColumnRenamed("concatenated", header)
这样就能精准替换掉值为"null"的字符串,而不会影响像annullment这类包含"null"子串的正常单词啦~
内容的提问来源于stack exchange,提问作者Sudarshan kumar
相关产品推荐
相关产品推荐

