【问题标题】:Adding custom Delimiter adds double quotes in the final spark data frame CSV outpu添加自定义分隔符在最终的 spark 数据帧 CSV 输出中添加双引号
【发布时间】:2017-10-29 16:15:44
【问题描述】:

我有一个数据框,我将在其中将默认分隔符 , 替换为 |^|。 它工作正常,我也得到了预期的结果,除非在记录中找到,。 例如,我有一个这样的记录,如下所示

4295859078|^|914|^|INC|^|Balancing Item - Non Operating Income/(Expense),net|^||^||^|IIII|^|False|^||^||^||^||^|False|^||^||^||^||^|505096|^|505074|^|505074|^|505096|^|505096|^||^|505074|^|True|^||^|3014960|^||^|I|!|

所以在第 4 个字段中有,

现在我这样做是为了替换,

 val dfMainOutputFinal = dfMainOutput.na.fill("").select($"DataPartition", $"StatementTypeCode",concat_ws("|^|", dfMainOutput.schema.fieldNames.filter(_ != "DataPartition").map(c => col(c)): _*).as("concatenated"))

val headerColumn = df.columns.filter(v => (!v.contains("^") && !v.contains("_c"))).toSeq

val header = headerColumn.dropRight(1).mkString("", "|^|", "|!|")

val dfMainOutputFinalWithoutNull = dfMainOutputFinal.withColumn("concatenated", regexp_replace(col("concatenated"), "null", "")).withColumnRenamed("concatenated", header)


dfMainOutputFinalWithoutNull.repartition(1).write.partitionBy("DataPartition","StatementTypeCode")
  .format("csv")
  .option("nullValue", "")
  .option("header", "true")
  .option("codec", "gzip")
  .save("s3://trfsmallfffile/FinancialLineItem/output")

我在保存的输出部分文件中得到这样的输出

"4295859078|^|914|^|INC|^|Balancing Item - Non Operating Income/(Expense),net|^||^||^|IIII|^|false|^||^||^||^||^|false|^||^||^||^||^|505096|^|505074|^|505074|^|505096|^|505096|^||^|505074|^|true|^||^|3014960|^||^|I|!|"

我的问题是" "在结果的开头和结尾。

如果删除逗号,那么我会得到正确的结果,如下所示

4295859078|^|914|^|INC|^|Balancing Item - Non Operating Income/(Expense)net|^||^||^|IIII|^|false|^||^||^||^||^|false|^||^||^||^||^|505096|^|505074|^|505074|^|505096|^|505096|^||^|505074|^|true|^||^|3014960|^||^|I|!|

【问题讨论】:

    标签: apache-spark spark-dataframe spark-csv


    【解决方案1】:

    这是一个标准的 CSV 功能。如果实际数据中出现分隔符(称为Delimiter Collision),则该字段用引号引起来。

    你可以试试

    df.write.option("delimiter" , somechar)
    

    其中somechar 应该是您的数据中没有出现的字符。

    编辑:

    一个更强大的解决方案是完全禁用quoteMode,因为您正在编写一个只有一列的数据框。

    dfMainOutputFinalWithoutNull.repartition(1)
      .write.partitionBy("DataPartition","StatementTypeCode")
      .format("csv")
      .option("nullValue", "")
      .option("quoteMode", "NONE")
    //.option("delimiter", ";")           // assuming `;` is not present in data
      .option("header", "true")
      .option("codec", "gzip")
      .save("s3://trfsmallfffile/FinancialLineItem/output")
    

    【讨论】:

    • 不是。您正在使用|^| 执行concat_ws。结果是一列。当您使用 Spark CSV 包编写它时,默认分隔符是 ,,它也存在于您的数据中,这就是它被封闭的原因。写入 HDFS 时必须更改分隔符。
    • 添加 .option("delimiter", ";") 您正在编写数据帧的位置。
    • @Anupam 通过使用此选项并选择数据中不存在的分隔符(;?),将避免此问题。
    • @Anupam 您还应该检查属性quoteMode 以获取 spark CSV。我相信您可以将其设置为.option("quoteMode", "NONE"),这将是一个比这更强大的解决方案。
    • @Anupam 使用 option("delimiter", "\001") 这是一个不可打印的字符 ^A,它不应该出现在您的数据中,除非它有问题。
    猜你喜欢
    • 2014-10-03
    • 1970-01-01
    • 2016-07-03
    • 2020-07-27
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多