Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何将spark数据帧保存为磁盘上的csv?_Scala_Apache Spark_Apache Spark Sql - Fatal编程技术网

Scala 如何将spark数据帧保存为磁盘上的csv?

Scala 如何将spark数据帧保存为磁盘上的csv?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,例如,此操作的结果: df.filter("project = 'en'").select("title","count").groupBy("title").sum() 将返回一个数组 如何将spark数据帧保存为磁盘上的csv文件?Apache spark不支持磁盘上的本机csv输出 不过,您有四种可用的解决方案: 您可以将数据帧转换为RDD: def CONVERTOREADABLESTRING(r:行)=??? df.rdd.map{convertToReadableString}.s

例如,此操作的结果:

df.filter("project = 'en'").select("title","count").groupBy("title").sum()
将返回一个数组


如何将spark数据帧保存为磁盘上的csv文件?

Apache spark不支持磁盘上的本机csv输出

不过,您有四种可用的解决方案:

  • 您可以将数据帧转换为RDD:

    def CONVERTOREADABLESTRING(r:行)=???
    df.rdd.map{convertToReadableString}.saveAsTextFile(文件路径)
    
    这将创建一个文件夹文件路径。在文件路径下,您将找到分区文件(例如part-000*)

    如果我想将所有分区附加到一个大的CSV中,我通常会做的是

    cat filePath/part* > mycsvfile.csv
    
    一些人将使用coalesce(1,false)从RDD创建一个分区。这通常是一种不好的做法,因为它可能会将您正在收集的所有数据拉到驱动程序中,从而使驱动程序不知所措

    请注意,
    df.rdd
    将返回一个
    rdd[Row]


  • 对于Spark我也有类似的问题。当我以客户端模式连接到集群时,我需要在驱动程序上写下csv文件

    我希望重用与ApacheSpark相同的CSV解析代码,以避免潜在的错误

    我检查了spark csv代码,在
    com.databricks.spark.csv.CsvSchemaRDD
    中找到了负责将数据帧转换为原始csv的代码

    遗憾的是,它是用
    sc.textFile
    和相关方法结尾硬编码的

    我复制粘贴了该代码,用
    sc.textFile
    删除了最后一行,并直接返回RDD

    我的代码:

    /*
      This is copypasta from com.databricks.spark.csv.CsvSchemaRDD
      Spark's code has perfect method converting Dataframe -> raw csv RDD[String]
      But in last lines of that method it's hardcoded against writing as text file -
      for our case we need RDD.
     */
    object DataframeToRawCsvRDD {
    
      val defaultCsvFormat = com.databricks.spark.csv.defaultCsvFormat
    
      def apply(dataFrame: DataFrame, parameters: Map[String, String] = Map())
               (implicit ctx: ExecutionContext): RDD[String] = {
        val delimiter = parameters.getOrElse("delimiter", ",")
        val delimiterChar = if (delimiter.length == 1) {
          delimiter.charAt(0)
        } else {
          throw new Exception("Delimiter cannot be more than one character.")
        }
    
        val escape = parameters.getOrElse("escape", null)
        val escapeChar: Character = if (escape == null) {
          null
        } else if (escape.length == 1) {
          escape.charAt(0)
        } else {
          throw new Exception("Escape character cannot be more than one character.")
        }
    
        val quote = parameters.getOrElse("quote", "\"")
        val quoteChar: Character = if (quote == null) {
          null
        } else if (quote.length == 1) {
          quote.charAt(0)
        } else {
          throw new Exception("Quotation cannot be more than one character.")
        }
    
        val quoteModeString = parameters.getOrElse("quoteMode", "MINIMAL")
        val quoteMode: QuoteMode = if (quoteModeString == null) {
          null
        } else {
          QuoteMode.valueOf(quoteModeString.toUpperCase)
        }
    
        val nullValue = parameters.getOrElse("nullValue", "null")
    
        val csvFormat = defaultCsvFormat
          .withDelimiter(delimiterChar)
          .withQuote(quoteChar)
          .withEscape(escapeChar)
          .withQuoteMode(quoteMode)
          .withSkipHeaderRecord(false)
          .withNullString(nullValue)
    
        val generateHeader = parameters.getOrElse("header", "false").toBoolean
        val headerRdd = if (generateHeader) {
          ctx.sparkContext.parallelize(Seq(
            csvFormat.format(dataFrame.columns.map(_.asInstanceOf[AnyRef]): _*)
          ))
        } else {
          ctx.sparkContext.emptyRDD[String]
        }
    
        val rowsRdd = dataFrame.rdd.map(row => {
          csvFormat.format(row.toSeq.map(_.asInstanceOf[AnyRef]): _*)
        })
    
        headerRdd union rowsRdd
      }
    
    }
    

    我遇到了类似的问题,我必须将数据帧的内容保存到我定义的名称为的csv文件中<代码>df.write(“csv”).save(“”正在创建目录而不是文件。因此,我们必须提出以下解决方案。 大部分代码取自下面的代码,对逻辑进行了少量修改

    def saveDfToCsv(df: DataFrame, tsvOutput: String, sep: String = ",", header: Boolean = false): Unit = {
        val tmpParquetDir = "Posts.tmp.parquet"
    
        df.repartition(1).write.
            format("com.databricks.spark.csv").
            option("header", header.toString).
            option("delimiter", sep).
            save(tmpParquetDir)
    
        val dir = new File(tmpParquetDir)
        val newFileRgex = tmpParquetDir + File.separatorChar + ".part-00000.*.csv"
        val tmpTsfFile = dir.listFiles.filter(_.toPath.toString.matches(newFileRgex))(0).toString
        (new File(tmpTsvFile)).renameTo(new File(tsvOutput))
    
        dir.listFiles.foreach( f => f.delete )
        dir.delete
        }
    

    将数据帧作为csv写入磁盘与从csv读取类似。如果希望将结果作为一个文件,可以使用coalesce

    df.coalesce(1)
          .write
          .option("header","true")
          .option("sep",",")
          .mode("overwrite")
          .csv("output/path")
    

    如果结果是数组,则应使用特定于语言的解决方案,而不是spark dataframe api。因为所有这些结果都返回驱动程序机器。

    我认为
    spark csv
    是首选解决方案。从头开始创建正确的csv行并不容易。所有的方言和正确的逃脱都是相当棘手的。在PySpark中,你们也可以将小桌子变成熊猫,并在当地进行保存。但这可能是一个Scala问题。如果您想在@zero323的答案中添加信息,请随意添加!伙计们,你们知道有没有可能避免hadoopish格式,并将数据存储到我选择的文件名或
    s3
    键名下的文件中,而不是
    \u success
    part-*
    ?我发布了使用spark csvbtw的解决方案。这不会返回数组,而是数据帧!如果给出的答案解决了您的问题,请接受它并进行投票,这样我们就可以将此问题归类为已解决!
    df.coalesce(1)
          .write
          .option("header","true")
          .option("sep",",")
          .mode("overwrite")
          .csv("output/path")