我不知道如何使用实木复合地板文件来做同样的事情

时间:2019-11-21 05:53:42

标签: scala apache-spark

Link to (data.csv) and (output.csv)

import org.apache.spark.sql._

    object Test {

      def main(args: Array[String]) {

        val spark = SparkSession.builder()
          .appName("Test")
          .master("local[*]")
          .getOrCreate()
        val sc = spark.sparkContext
        val tempDF=spark.read.csv("data.csv")
        tempDF.coalesce(1).write.parquet("Parquet")
        val rdd = sc.textFile("Parquet")

我将data.csv转换为优化的实木复合地板文件,然后加载它,现在我想对实木复合地板文件进行所有转换,就像我对下面给出的csv文件所做的一样,然后将其另存为实木复合地板文件。{ {3}}

    val header = rdd.first
    val rdd1 = rdd.filter(_ != header)
    val resultRDD = rdd1.map { r =>
      val Array(country, values) = r.split(",")
      country -> values
    }.reduceByKey((a, b) => a.split(";").zip(b.split(";")).map { case (i1, i2) => i1.toInt + i2.toInt }.mkString(";"))

    import spark.sqlContext.implicits._
    val dataSet = resultRDD.map { case (country: String, values: String) => CountryAgg(country, values) }.toDS()
    dataSet.coalesce(1).write.option("header","true").csv("output")

  }

  case class CountryAgg(country: String, values: String)

}

2 个答案:

答案 0 :(得分:1)

我认为您正在尝试基于corresponding elements from the array来添加Country。我已经使用DataFrame APIs完成了此操作,这使工作更加轻松。

代码供您参考:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window

val df = spark.read
              .format("csv")
              .option("header", "true")
              .option("inferSchema", "true")
              .option("path", "/path/to/input/data.csv")
              .load()


val df1 = df.select(
                $"Country", 
                (split($"Values", ";"))(0).alias("c1"),
                (split($"Values", ";"))(1).alias("c2"),
                (split($"Values", ";"))(2).alias("c3"),
                (split($"Values", ";"))(3).alias("c4"),
                (split($"Values", ";"))(4).alias("c5")
             )
             .groupBy($"Country")
             .agg(
             sum($"c1" cast "int").alias("s1"),
             sum($"c2" cast "int").alias("s2"),
             sum($"c3" cast "int").alias("s3"),
             sum($"c4" cast "int").alias("s4"),
             sum($"c5" cast "int").alias("s5")             
             )
             .select(
                $"Country", 
                concat(
                    $"s1", lit(";"), 
                    $"s2", lit(";"), 
                    $"s3", lit(";"), 
                    $"s4", lit(";"), 
                    $"s5"
                ).alias("Values")
            )

df1.repartition(1)
    .write
    .format("csv")
    .option("delimiter",",")
    .option("header", "true")
    .option("path", "/path/to/output")
    .save()

以下是输出供您参考。

scala> df1.show()
+-------+-------------------+
|Country|             Values|
+-------+-------------------+
|Germany| 144;166;151;172;70|
|  China| 218;239;234;209;75|
|  India| 246;153;148;100;90|
| Canada| 183;258;150;263;71|
|England|178;114;175;173;153|
+-------+-------------------+
  

P.S .:

     
      
  1. 您可以将输出格式更改为parquet/orc或任何所需的格式。

  2.   
  3. 我将repartitioned df1放入了1分区中,以便可以得到一个single output file。您可以选择是否重新分区   在您的用例上

  4.   

希望这会有所帮助。

答案 1 :(得分:0)

您可以将文件读取为镶木地板,然后对生成的数据帧执行相同的操作:

val spark = SparkSession.builder()
    .appName("Test")
    .master("local[*]")
    .getOrCreate()

// Read in the parquet file created above
// Parquet files are self-describing so the schema is preserved
// The result of loading a Parquet file is also a DataFrame
val parquetFileDF = spark.read.parquet("data.parquet")

如果您需要rdd,则可以致电:

val rdd = parquetFileDF.rdd

您可以像以前一样继续进行转换,并像问题中一样以拼花形式书写。