j'ai un dataframe à partir d'une source SQL qui ressemble à:
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]
Je souhaite partitionner et écrire ces données dans des fichiers csv dans lesquels chaque partition est basée sur la lettre initiale du pays. La Biélorussie et la Belgique doivent donc figurer dans le fichier de sortie, l'Autriche et l'Australie dans l'autre.
Voici ce que vous pouvez faire
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")
Édité: Vous pouvez également utiliser la sous-chaîne qui peut augmenter les performances suggérées par Raphel
substring(Column str, int pos, int len)
La sous-chaîne commence à pos et est de longueur len lorsque str est de type chaîne ou renvoie la tranche d'octet qui commence à pos en octet et a une longueur de len lorsque str vaut Type binaire
val result = df.withColumn("firstCountry", substring($"country",1,1))
puis utilisez partitionby avec write
J'espère que ceci résoudra votre problème!
Une solution pour résoudre ce problème serait de créer une colonne contenant uniquement la première lettre de chaque pays. Ceci fait, vous pouvez utiliser partitionBy
pour enregistrer chaque partition dans des fichiers distincts.
dataFrame.write.partitionBy("column").format("com.databricks.spark.csv").save("/path/to/dir/")