【问题标题】:Write/store dataframe in text file在文本文件中写入/存储数据帧
【发布时间】:2017-06-14 07:12:15
【问题描述】:

我正在尝试将dataframe 写入text 文件。如果文件包含单列,那么我可以在文本文件中写入。如果文件包含多列,那么我将面临一些错误

文本数据源只支持单列,你有 2 列。

object replace {

  def main(args:Array[String]): Unit = {

    Logger.getLogger("org").setLevel(Level.ERROR)

    val spark = SparkSession.builder.master("local[1]").appName("Decimal Field Validation").getOrCreate()

    var sourcefile = spark.read.option("header","true").text("C:/Users/phadpa01/Desktop/inputfiles/decimalvalues.txt")

     val rowRDD = sourcefile.rdd.zipWithIndex().map(indexedRow => Row.fromSeq((indexedRow._2.toLong+1) +: indexedRow._1.toSeq)) //adding prgrefnbr               
                         //add column for prgrefnbr in schema
     val newstructure = StructType(Array(StructField("PRGREFNBR",LongType)).++(sourcefile.schema.fields))

     //create new dataframe containing prgrefnbr

     sourcefile = spark.createDataFrame(rowRDD, newstructure)
     val op= sourcefile.write.mode("overwrite").format("text").save("C:/Users/phadpa01/Desktop/op")

  }

}

【问题讨论】:

    标签: scala apache-spark


    【解决方案1】:

    您可以将数据框转换为 rdd 并将行转换为字符串并将最后一行写为

     val op= sourcefile.rdd.map(_.toString()).saveAsTextFile("C:/Users/phadpa01/Desktop/op")
    

    已编辑

    正如@philantrovert 和@Pravinkumar 所指出的那样,上述内容将在输出文件中附加[],这是真的。解决方案是将replace 他们与empty 字符作为

    val op= sourcefile.rdd.map(_.toString().replace("[","").replace("]", "")).saveAsTextFile("C:/Users/phadpa01/Desktop/op")
    

    甚至可以使用regex

    【讨论】:

    • 我认为这会在每行的两端添加[]
    • 但它在每行的每条记录中添加“[]”。例如:[2,12.2,12.2]
    • 是的,你可以用空替换它。让我更新答案
    • 是的,我可以阅读,但“欧元”符号读取为 garbej 值。输入值 = €|€,输出值 =“�|�”。转换后
    • 我猜这是一个序列化和反序列化问题。这可能是 SO 中的另一个问题。 @PravinkumarHadpad 你怎么说?
    【解决方案2】:

    我建议使用csv 或其他分隔格式。以下是在 Spark 2+ 中以最简洁/优雅方式写入 .tsv 的示例

    val tsvWithHeaderOptions: Map[String, String] = Map(
      ("delimiter", "\t"), // Uses "\t" delimiter instead of default ","
      ("header", "true"))  // Writes a header record with column names
    
    df.coalesce(1)         // Writes to a single file
      .write
      .mode(SaveMode.Overwrite)
      .options(tsvWithHeaderOptions)
      .csv("output/path")
    

    【讨论】:

    • 这不是写tsv文件而是写csv
    • 注意"delimiter", "\t" 选项。它应该可以工作(对我有用)
    • 我在 Spark 2.4 中有完全相同的代码,它写入一个 CSV。此外,我没有找到解决方案。
    • 在 2.3 中为我工作。我想知道这里是否发生了其他事情......
    【解决方案3】:

    您可以保存为文本 CSV 文件 (.format("csv"))

    结果将是一个 CSV 格式的文本文件,每列将用逗号分隔。

    val op = sourcefile.write.mode("overwrite").format("csv").save("C:/Users/phadpa01/Desktop/op")
    

    更多信息可以在spark programming guide找到

    【讨论】:

    • 我希望文件扩展名应该是.txt,上面的解决方案文件扩展名是.csv
    • 您希望如何打印每一行?逗号分隔还是其他?
    • @PravinkumarHadpad - 你为什么关心输出文件扩展名是 .txt 还是 .csv?
    • 在添加 seq number.eg:- 3,"12.20,12.2-" 之前,它为数据框中可用的值附加双引号,但我想要输出文件数据,如 3,12.20,12.2
    • 基本上我想要双引号释放文件,这就是为什么我想将它存储在文本文件中。
    【解决方案4】:

    我认为使用“子字符串”更适合我感觉的所有场景。

    请检查以下代码。

    sourcefile.rdd
    .map(r =>  { val x = r.toString; x.substring(1, x.length-1)})
    .saveAsTextFile("C:/Users/phadpa01/Desktop/op")
    

    【讨论】:

      【解决方案5】:

      我使用 databricks api 将我的 DF 输出保存到文本文件中。

      myDF.write.format("com.databricks.spark.csv").option("header", "true").save("output.csv")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-01
        • 2015-11-25
        • 1970-01-01
        • 1970-01-01
        • 2019-04-13
        • 2018-11-20
        相关资源
        最近更新 更多