根据列值对火花数据帧进行分区?

时间:2017-07-07 07:09:17

标签: scala apache-spark apache-spark-sql

我有一个来自sql源的数据框,如下所示:

User(id: Long, fname: String, lname: String, country: String)

[1, Fname1, Lname1, Belarus]
[2, Fname2, Lname2, Belgium]
[3, Fname3, Lname3, Austria]
[4, Fname4, Lname4, Australia]

我想将这些数据分区并写入csv文件,其中每个分区都基于该国家的首字母,因此白俄罗斯和比利时应该是输出文件中的一个,奥地利和澳大利亚应该是其中一个。

2 个答案:

答案 0 :(得分:7)

这是你可以做的事情

import org.apache.spark.sql.functions._
//create a dataframe with demo data
val df = spark.sparkContext.parallelize(Seq(
  (1, "Fname1", "Lname1", "Belarus"),
  (2, "Fname2", "Lname2", "Belgium"),
  (3, "Fname3", "Lname3", "Austria"),
  (4, "Fname4", "Lname4", "Australia")
)).toDF("id", "fname","lname", "country")

//create a new column with the first letter of column
val result = df.withColumn("countryFirst", split($"country", "")(0))

//save the data with partitionby first letter of country 

result.write.partitionBy("countryFirst").format("com.databricks.spark.csv").save("outputpath")

<强>编辑: 您还可以使用子字符串,它可以提高Raphel建议的性能

  

substring(Column str, int pos, int len)子串从pos开始,是   当str是String类型或返回byte的切片时,长度为len   数组以字节开头于pos,当str为时长度为len   二进制类型

val result = df.withColumn("firstCountry", substring($"country",1,1))

然后使用partitionby with write

希望这能解决你的问题!

答案 1 :(得分:0)

解决此问题的另一种方法是首先创建一个仅包含每个国家/地区的第一个字母的列。完成此步骤后,您可以使用partitionBy将每个分区保存为单独的文件。

dataFrame.write.partitionBy("column").format("com.databricks.spark.csv").save("/path/to/dir/")