Cette étude porte sur la brique Spark SQL de la plateforme Apache Spark.
L'objectif est de présenter les concepts et les fonctionnalités de spark SQL.
Les points abordés sont :
- Architecture
- API de Spark SQL
- Opérations sur DataFrames/DataSets
- Opérations relatives au nettoyage de données
- Opérations de conversion (DataFrame, DataSet, Collection, RDD)
- Opérations relationnelles
Interface fonctionnelle, Lambda expression, méthode par défaut, référence de...
Spark SQL principes et fonctions
1. APACHE SPARK : SPARK SQL PRINCIPES ET FONCTIONS
DR MUSTAPHA MICHRAFY
CONTACT : DATASCIENCE.KM@GMAIL.COM
2. CONTEXTE
Cette étude a été menée dans le cadre des
rencontres de travail organisées au Laboratoire
CERMSEM, Centre d'Économie de la Sorbonne (CES).
Il vise à présenter Spark SQL:
• Architecture
• API de Spark SQL
• Opérations sur DataFrames
• Opérations sur DataSet
• Opérations relationnelles
2
M.MICHRAFY
3. PLAN
1. Contexte
2. Objectif et prérequis
3. Spark SQL, Motivations
4. Spark SqL et introduction de Catalyst Optimizer
5. Aperçu sur les objets du module Spark SQL
6. Nouvelle architecture Spark ( 2.x)
7. DataWorkflow et Catalyst Optimizer
8. Zoom sur SParkSESSION
9. DataSet et DataFrame
10.DataFrame, caractéristiques, formats supportés, création
11.Chargement et persistance des données
12.DataFrameNaFunctions et Préparation des données
13.Graphe de conversion entre Collection, RDD, DataFrame et DataSet
14.Opérations sur les DataSets et les DataFrames
3
M.MICHRAFY
4. OBJECTIF ET PRÉREQUIS
• Connaissance de l’approche objet
• Connaissance de la programmation
fonctionnelle
• Connaissance du langage Scala
• Connaissance de Spark
Cette étude porte sur la brique Spark SQL de
la plateforme Apache Spark. Il vise à
présenter les concepts et les fonctionnalités
de spark SQL.
PrérequisObjectif
4
M.MICHRAFY
5. SPARK SQL : DÉFINITION ET MOTIVATIONS ?
• SPARK SQL est une brique logiciel incontournable
de la plate forme Apache Spark.
• Cette brique est dédiée au traitement de
données structurées et semi structurées via l’API
DataSet/DataFrame.
• Spark SQL permet d’effectuer des requêtes sur les
données avec une syntaxe similaire à SQL.
• Spark SQL permet de s’interfacer à diverses
sources de données.
• Les opérations de SPARK SQL sont optimisées à
travers l’utilisation de Catalyst Optimizer.
• Pour formater les données
• Pour extraire des caractéristiques des données
• Pour enrichir les données
• Pour transformer les données
• Pour appliquer des opérations relationnelles
SPARK SQL ? Fonctionnalités
5
M.MICHRAFY
• S’interfacer avec un tableau de bord en utilisant
tableau, Qlik
• Réaliser des requêtes SQL sans faire appel à la
sémantique RDD
• Préparation et Analyse des données à travers l’utilisation
de l’API DataFrame/DataSet avec opérations optimisées
et riches à l’image du package dplyr de R
Cas d’utilisation
6. SPARK SQL ET INTRODUCTION DE CATALYST OPTIMIZER
6
La popularité des systèmes
relationnels montre que les
utilisateurs favorisent l’écriture des
requêtes déclaratives.
Constat 1
L’approche relationnelle
est insuffisante pour la
majorité des applications
BigData, car :
Limite
Un besoin pour des opérations ETL vers et
à partir de diverses sources de données,
(semi) structurée, nécessitant un code
personnalisé.
L’analyse avancée -basée sur des
algorithmes complexes- ne peut être
réalisée par l’approche relationnelle
1
2
Les workflows de données
peuvent être exprimés par une
combinaison de requêtes
relationnelles et d’algorithmes
complexes.
Constat 2
Ces deux systèmes - relationnel et procédural – sont restés jusqu'à la
version 1.0.2 de Spark largement disjointes, forçant les utilisateurs à
choisir un paradigme ou l'autre.
À noter …
• Il vise à combiner l’approche relationnelle et procédurale dans la brique spark SQL.
o API DATASET/DataFrame permet d’effectuer des opérations relationnelles sur des sources de
données externes et les collections intégrées de Spark
o Divers formats de données et algorithmes distribués supportés via l’introduction de l’optimiseur
Catalyst
Intérêt de SPARK SQL
7. APERÇU SUR LES OBJETS DU MODULE SPARK SQL
7
Objets
Spark SQL
Point d’entrée pour l’API
DataSet et l’API DataFrame
DataSet est une collection
distribuée immutable, disposant
d’opérations de type action et
transformation. DataFrame est
un DataSet de Type Row
Interface pour charger des
DataSet à partir d’un stockage
externe (TXT, CSV, JSON,
PARQUET, Cle/Valeur, JDBC)
Interface pour persister les
données d’une DataSet vers un
système de stockage externe
Trait qui représente
une colonne
Trait qui représente
une ligne
Point d’entrée pour le module
Spark SQL de la version 1.0.1 à
la version 1.6 de Spark
Collection des méthodes
implicites pour convertir
des Objets Scala en
DataSets
SQLImplicits
SQLContext
Row
Column
DataFrameWriter
DataFrameReader
DataSet & DataFrame
SparkSession
8. NOUVELLE ARCHITECTURE SPARK ( 2.X)
8
Spark Core (RDD)
SQL
ML Pipelines
Catalyst Optimizer
DataSet/DataFrame
Structured
Streaming
GraphFrame
Storage
Spark
SQL
o La nouvelle architecture s’appuie sur le
module Catalyst Optimizer permettant
d’unifier les APIs et optimiser davantage le
traitement .
o DataSet = DataFrame[Row]
o DataSet, DataFrame et SQL partagent les
mêmes étapes d’optimisation et
d’exécution grâce à Catalyst Optimizer
9. DATAWORKFLOW ET CATALYST OPTIMIZER
9
SQL AST
DataFrame
DataSet
RDDs
Catalyst Optimizer
Query Plan Optimization
Query
Transformation Génération du code
10. SPARKSESSION
10
• SparkSession est le point d’entrée de l’API
DataSet/Dataframe, depuis la version 2.0.0
• SparkSession est une classe qui peut être créée à
partir du Builder.
• Elle appartient au package org.apache.spark.sql
Point d’entrée
• Accéder à SparkContext
• Accéder à SparkSql pour garantir la cohérence des versions
de Spark SQL
• Créer des DataFrames à partir des RDD ou des collections
• Créer des DataSet
• Créer une DataFrame ou une DataSet vide
• Créer une DataSet avec une seule colonne
• Exécuter une requête Sql et retourner une dataframe.
• Accéder à des Interfaces permettant de charger une
DataSet, en mode batch ou flux continu, à partir de
systèmes de stockage externes (TEXT, CSV, JSON, ORC,
PARQUET, Cle/valeur, JDBC)
Fonctionnalités
• La majorité des méthodes sont au stade expérimental et sont disponibles à partir de la version 2.
• D’autres méthodes sont dédiés aux développeurs de l’API Spark
• Avant la version 2.0.0, la classe utilisée est SparkSql
À noter bien
• Builder est une classe interne pour SparkSession.
• Cette dernière permet de gérér, créer et
configurer une session spark SQL
• Il dispose de :
• Constructeur sans argument
• appName pour fixer le nom de l’application
• Config pour fixer les options de la conf.
• getOrCreate pour retourner une session
Builder
11. DATASET ET DATAFRAME
11
• DataSet est une collection distribuée de données
• L’Api DataSet a été introduit dans Spark à partir
de la version 1.6.
• La dataSet est fortement typée.
• DataSet supporte des transformations basées sur
des paradigmes fonctionnels ou relationnels
• À l’image de la RDD, une DataSet dispose des
opérations de type transformation et Action.
• Une DataSet est paresseuse, par conséquent le
calcul se déclenche pour des opérations de type
action.
• L’API DataSet est disponible pour le langage
Scala et Java, pas pour Python
DataSet
• DataFrame est une DataSet avec des éléments
de type Row.
• Une DataFrame est l’équivalent d’une table dans
une base de données ou une dataFrame dans R
ou Python.
• Une DataFrame est non typée.
• Une DataFrame peut être construite à partir
d’une source de données structurées, des tables
Hive, des BD ou des RDDs.
• L’API DataFrame est disponible en Scala, Java,
Python et R.
DataFrame
L’API SPARK SQL s’articule autour de
de la notion de DataSet/DataFrame
12. DATAFRAME, CARACTÉRISTIQUES, FORMATS SUPPORTÉS, CRÉATION
12
Cinq manières de créer une DataFrame
1. A partir d’une source de données
2. À partir d’une RDD
3. À partir d’une table BD
4. A partir d’une table Hive
5. Via une opération de
transformation
Création
La dataFrame supporte :
des opérations de type transformation et
action.
des opérateurs relationnels : select, where,
join, groupby.
les langages Scala, Java, Python, R
Elle est :
Orientée colonne
Partionnée
d’une évaluation paresseuse
DataSet = DataFrame[Row]
Caractéristique
In-Memory
Immutable
Lazy
evaluated
Cacheable
Parallele
unTyped
Resilient DataFrame
Spark SQL supporte de charger ou
d’enregistrer des fichiers dans
divers formats : non structuré, semi-
structuré, structuré.
Les formats sont :
o Text
o Json
o CSV
o Parquet
o Orc
Formats fichiers
M.MICHRAFY
Partitioned
13. CHARGEMENT ET PERSISTANCES DES DONNÉES 1/2
13
• DataFrameReader a pour objectif de charger des
DataSet à partir d’un système de stockage externe
tels qu’un système de fichier, une table relationnelle,
un stockage clé-valeur, etc.
• L’accès à cette classe se fait à partir d’une session
sparkSession via le membre read.
• Elle dispose des méthodes dédiées à des formats
de type TXT, JSON, Parquet, Orc, CSV. Pour cela,
utiliser les méthodes txt, json, orc, csv, parquet,
textFiles, jdbc…
• Elle dispose aussi d’une méthode générique, notée
load, nécessitant la spécification du format, du
schéma et des options.
• La majorité des méthodes de chargement
retournent des dataFrames à l’exception de la
méthode textFiles retourne une DataSet[String]
DataFrameReader
• DataFrameWriter permet de persister des DataSet
dans un système de stockage externe tels qu’un
système de fichier, JDBS, HIVE, Stockage clé-valeur,
etc.
• L’accès à cette classe se fait à partir d’une session
sparkSession via le membre write.
• Cette classe dispose des méthodes :
• format : spécifier le format de données (json, txt,
parquet, orc, csv)
• modeSave : préciser le comportement lorsque
la donnée ou la table existe.
• Option(s) : ajouter une ou plusieurs options
relative la source de données de sortie
• save : enregistrer le contenu de la dataFrame
• jdbc, csv, parquet, orc, txt : sont des méthodes
pour enregistrer le contenu dans un format
spécifique.
DataFrameWriter
Dans la classe DataFrameReader (resp. DataFrameWriter), les méthodes csv, json,
orc, parquet, txt sont des cas particuliers de la méthodes load (resp. save).
14. DATAFRAMENAFUNCTIONS ET PRÉPARATION DES DONNÉES
14
• Il offre des fonctionnalités pour gérer les valeurs
manquantes dans une dataFrame.
• Une instance de cette classe peut être créée en
faisant appel à la méthode na de la dataSet.
• C’est une classe «final». Par conséquent, elle
n’est pas extensible
• Il fait partie du package org.apache.spark.sql
Caractéristiques
• Méthodes de type drop : elles permettent de
supprimer des lignes ou des colonnes contenant
null or NaN, selon certains critères et retournent
une nouvelle dataFrame
• Méthodes de type fill : elles permettent de
substituer certaines valeurs (nulles ou NaN) et
retournent une nouvelle DataFrame
• Méthodes de type replace : elles permettent de
remplacer des occurrences de certaines
colonnes par d’autres.
Fonctionnalités
Une instance de cette classe est utile dans la
phase de préparation des données.
15. GRAPHE DE CONVERSION ENTRE LA RDD, DATAFRAME, DATASET
15
RDD DataFrame
DataSetCollection
Une RDD peut etre transformée en DataSet en
utilisant la méthode toDS()
Une RDD peut être transformée en DataFrame en
utilisant la méthode toDF()
Une Collection peut être transformée en RDD en
utilisant la méthode parallelize du sparkContext
Une Collection peut être transformée en DataSet
en utilisant toDS()
Une collection peut être transformée en
DataFrame en utilisant toDF()
Une DataFrame peut être transformée en DataSet
en utilisant as[U](encoder)
Le contenu d’une DataSet/DataFrame peut être
représentée par une RDD en utilisant le membre
rdd de la DataSet.
16. 16
Opérations sur les DataSet/DataFrame
• Cette section présente les différentes opérations relatives à une
DataFrame/DataSet :
1. Opération de type Action/transformations sur DataFrame/DataSet
2. Construction d’une DataFrame/DataSet
3. Conversion entre DataSet/DataFrame/RDD/Collection
4. Opérations SQL
5. Opérations de nettoyage de données
(*) : Les exemple du code ont été exécutés avec spark-shell, version 2.0.2
M.MICHRAFY
18. SPARKSESSION : CREATION ET CONFIGURATION
SparkSession est le point d’entrée
pour le module Spark Sql
La création d’un objet SparkSession se
fait via l’objet builder qui est une
classe interne de SparkSession
package : org.apache.spark.sql
Objectif
// importer sparkSession
import org.apache.spark.sql.SparkSession
/***
Créer sparkSession
Nommer l’application
Configurer l’application
en enfin retourner la session crée.
****/
// retour > spark: org.apache.spark.sql.SparkSession =
org.apache.spark.sql.SparkSession@5fd8dd66
val spark = SparkSession .builder()
.appName("Spark SQL")
.config("spark.some.config.option", "value")
.getOrCreate()
// afficher la version de spark
// retour > res1: String = 2.0.2
spark.version
Exemple
18
M.MICHRAFY
Importer le package SparkSession
Créer la session SparkSession
Afficher la version de spark
19. CRÉATION D’UNE DATAFRAME À PARTIR D’UNE SÉQUENCE
createDataFrame est une méthode
de la classe SparkSession permettant
de créer une dataFrame à partir
d’une collection.
Objectif
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // créer une session
// créer des sequences : seqVilles
val seqVilles = Seq(("Paris", 2015, 8),("Paris", 2015, 8),("Lyon", 2016, 7),("Lyon",
2017, 1),("Lyon", 2016, 7))
// créer une dataFrame à partir de la séquence seqVilles
val dfVilles = spark.createDataFrame(seqVilles).toDF("ville", "annee", "mois")
// dfVilles: org.apache.spark.sql.DataFrame = [ville: string, annee: int ... 1 more field]
dfVilles.printSchema // afficher le schéma de la dataFrame dfVille
root
|-- ville: string (nullable = true)
|-- annee: integer (nullable = false)
|-- mois: integer (nullable = false)
dfVilles.show() // afficher le contenu de la dataframe
|ville|annee|mois|
|Paris| 2015 | 8|
|Paris| 2015 | 8|
| Lyon| 2016| 7|
| Lyon| 2017| 1|
| Lyon| 2016| 7|
Exemple
19
M.MICHRAFY
Importer le package SparkSession
Créer la session SparkSession
Créer la séquence
Créer la DataFrame à partir de la
séquence
Afficher le schema de la dataFrame
Afficher le contenu de la dataFrame
20. DATAFRAME/DATAFRAMEREADER : CREATION À PARTIR D’UNE DATASOURCE
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
val dfReader = spark.read //Pointer la DataFrameReader
// Retour > org.apache.spark.sql.DataFrameReader@a323a5b
// Créer des dataFrames via des fichier Json,
val dfJSON = dfReader.json("VotrPathSpark/people.json")
// retour > df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
val dfCSV = dfReader.cvs("VotrPathSpark/people.txt")
// retour > dfcsv: org.apache.spark.sql.DataFrame = [_c0: string, _c1: string]
val dfparquet = dfReader.parquet("VotrPathSpark/users.parquet")
//retour > dfparquet: org.apache.spark.sql.DataFrame = [_c0: string, _c1: string ... 1 more field]
val dfTEXT = dfReader.txt("VotrPathSpark/people.txt")
// retour > dfTXT: org.apache.spark.sql.DataFrame = [value: string]
// afficher le contenu des dataframes avec la methode show()
dfJSON.show()
dfCSV.show()
dfTEXT.show()
Exemple
20
M.MICHRAFY
SparkSession dispose d’un membre
noté read de type DataFrameReader
DataFrameReader permet de
charger une dataFrame ou une
DataSet via :
• Un fichier format CSV
• Un fichier format TXT
• Un fichier format JSON
• Un fichier format Parquet
• Un fichier format ORC
• Une table JDBC
DataFrameReader permet aussi de
spécifier le shéma.
DataFrameReader
Créer la session
SparkSession
Pointer le membre
DataFrameReader
Charger le fichier JSON
21. LANCER DES REQUÊTES SQL SUR UNE VUE TEMPORAIRE
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// Créer des dataFrames à partir d’un fichier Json,
val dfJSON = spark.read.json("VotrPathSpark/people.json")
// retour > df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
/*****
créer une vue temporaire,
puis lancer des requetes sur la vue
****/
val sqlDfJson = dfJSON.createOrReplaceTempView("people") // créer la vue temp.
val sqlDF = spark.sql("SELECT * FROM people where age > 18") // interroger la vue
//retour > sqlDF: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
// afficher le contentu de la dataFrame sqlDF
sqlDF.show()
Retour > |age| name|
| 30 | Andy |
| 19 |Justin |
Exemple
21
M.MICHRAFY
createOrReplaceTempView
est une méthode de DataSet
permettant de créer une vue
pour exécuter des requêtes
SQL.
La méthode sql de DataSet
permet d’interroger une vue
temporaire et retourne une
DataFrame
La vue temporaire est
accessible tant que la session
Spark SQL est disponible.
Requête SQL
Créer la session SparkSession
Charger le fichier Json
Créer une vue temporaire
Lancer une requête sur la vue
Afficher le résultat
de la requête
22. CONVERSION D’UNE COLLECTION EN UNE DATASET
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
//créer une classe case
Case class Person(name:String, age:Int)
//créer une dataSet
val ps = Seq(Person(”Alain", 30), Person("Stef", 19), Person("Sam", 25)).toDS()
//retour > ps: org.apache.spark.sql.Dataset[Person] = [name: string, age: bigint]
// afficher les noms des colonnes
ps. Columns
// retour > res1: Array[String] = Array(name, age)
// afficher le schèma de la dataSet
ps.schema
//Retour > res2: org.apache.spark.sql.types.StructType =
StructType(StructField(name,StringType,true), StructField(age,LongType,false))
// afficher le contenu de la dataSet dans un tableau
ps.collect()
// Retour >res3: Array[Person] = Array(Person(Andy,32), Person(Stef,19), Person(Sam,25))
Exemple
22
M.MICHRAFY
Spark SQL dispose des services
permettant de convertir une
collection en DataSet
Ce mécanisme s’appuie sur
les encoders.
la méthode toDS() permet de
convertir un Collection vers
une DataSet.
Requête SQL
Créer la session SparkSession
Créer la classe case
Créer la dataSet
Afficher les nom des colonnes
Afficher le schéma
Afficher le contenu
de la dataSet
23. CONVERSION UNE DATAFRAME EN UNE DATASET
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// Créer la dataFrame à partir d’un fichier Json,
val dfjson = spark.read .json ("VotrPathSpark/people.json")
// retour > org.apache.spark.sql.DataFrame = [age: bigint, name: string]
dfjson.printSchema // afficher le schema de dfjson
// root
|-- age: long (nullable = true)
|-- name: string (nullable = true)
case class Person(name:String, age:Long) //créer une classe case
val DfTODS = dfjson.as[Person] //Convertir la DataFrame en une DataSet
//DfTODS: org.apache.spark.sql.Dataset[Personne] = [age: bigint, name: string]
DfTODS .schema
//Retour > org.apache.spark.sql.types.StructType =
StructType(StructField(age,LongType,true), StructField(name,StringType,true))
Exemple
23
M.MICHRAFY
En Spark SQL, il est possible de
convertir une DataFrame vers
une DataSet
Pour cela, il suffit d’utiliser la
méthode as de la Dataframe
avec le nom de la classe.
Requête SQL
Créer la session SparkSession
Créer la classe case
Créer la dataFrame
Afficher le schéma de
la DataSet
Convertir la DataFrame
en DataSet
24. CONVERSION D’UNE RDD EN DATAFRAME
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// Créer une RDD à partir du fichier txt
val peopleRDD = spark.sparkContext
.textFile("VotrePathSpark/people.txt")
.map(_.split(","))
.map(attributes => Person(attributes(0), attributes(1).trim.toInt))
// retour > peopleRDD: org.apache.spark.rdd.RDD[Person] = MapPartitionsRDD[79]
peopleRDD.cache() // persister la RDD en mémoire
// retour > peopleRDD.type = MapPartitionsRDD[94] at map at <console>:31
//Convertir la RDD en DataFrame
val peopleDS = peopleRDD.toDF()
//retour > peopleDS: org.apache.spark.sql.DataFrame = [name: string, age: bigint]
peopleDS .show() // afficher le contenu de la dataFrame
| name |age|
|Michael| 29 |
| Andy | 30 |
| Justin | 19 |
Exemple
24
M.MICHRAFY
En Spark SQL, il est possible de
convertir une RDD en une
DataFrame
Pour ce faire, il suffit d’utiliser
la méthode toDF de la RDD
Requête SQL
Créer la session SparkSession
Persister la RDD en mémoire
Créer la RDD
Afficher la DataFrame
Convertir la RDD en
DataFrame
25. CONVERSION D’UNE RDD EN DATAFRAME : SPÉCIFIER LE SCHÉMA
import org.apache.spark.sql.{SparkSession, Row} // importer sparkSession, Row
import org.apache.spark.sql.types._
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// Créer une RDD de type Row à partir du fichier txt
val peopleRDD = spark.sparkContext
.textFile("VotrePathSpark/people.txt")
.map(_.split(","))
.map(attributes => Row(attributes(0), attributes(1).trim.toInt))
// retour > peopleRDD: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] =
MapPartitionsRDD[111]
val schemaString = "name age"
val fields = schemaString.split(" ").map(w => StructField(w, StringType, nullable = true))
//retour > fields: Array[org.apache.spark.sql.types.StructField] =
Array(StructField(name,StringType,true), StructField(age,StringType,true))
val schema = StructType(fields)
//Convertir la RDD en DataFrame
val peopleDF = spark.createDataFrame(peopleRDD, schema)
// peopleDF: org.apache.spark.sql.DataFrame = [name: string, age: string]
Exemple
25
M.MICHRAFY
En Spark SQL, il est aussi
possible de convertir une RDD
de type Row en une
DataFrame en spécifiant le
schéma.
createDataFrame est une
méthode de sparkSession
permettant de créer une
DataFrame à partir d’une
RDD[Row] et le schéma
associé à Row
Requête SQL
Importer les packages
Créer la session
SparkSession
Créer la RDD[Row]
Créer le schéma
Convertir la RDD en
DataFrame
26. FONCTIONS GÉNÉRIQUES POUR LA CHARGEMENT ET LA PERSISTANCE
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// charger le fichier people.json en utilisant la méthode generique load
val fgl = spark.read.format("json").load("VotrePathSpark/people.json")
//retour > org.apache.spark.sql.DataFrame = [age: bigint, name: string]
//afficher le contenu sous forme d’un tableau
flg.collect()
// retour > Array[org.apache.spark.sql.Row] = Array([null,Michael], [30,Andy], [19,Justin])
// importer SaveMode
import org.apache.spark.sql.SaveMode
//Persister le contenu de la dataframe en utilisant save
val fgs = fgl.write.format("parquet").mode(SaveMode.ErrorIfExists).save("people.parquet")
Exemple
26
M.MICHRAFY
Spark SQL dispose de deux
fonctions génériques pour le
chargement ou la persistance
des données vers ou à partir
d’un système de stockage
externe.
load (Resp. save) est une
méthode de la classe
DataFrameReader(resp
DataSet) pour charger (resp.
Persister ) des données.
La méthode load nécessite
de préciser le format des
données, alors que la
méthode save nécessite de
spécifier le mode de
sauvegarde.
mode est une méthode de la
calsse DataFrameWriter,
permettant de spécifier le
comportement si le fichier ou
la table existe.
Load / Save
27. PERSISTER LE CONTENU D’UNE DATAFRAME
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// créer une dataFrame
val villes = spark.createDataFrame(Seq(("Paris",2015,8),("Lyon",2015,8)
,("Toulon",2016,7))).toDF("ville","annee","mois")
//villes: org.apache.spark.sql.DataFrame = [ville: string, annee: int ... 1 more field]
// Persister le contenu en format json, csv et parquet
villes.write.json("villes.json")
villes.write.csv("villes.csv")
villes.write.parquet("villes.parquet")
Exemple
27
M.MICHRAFY
En Spark SQL, il est possible de
persister le contenu d’une
dataFrame en different
format : format JSON, CSV,
PARQUET, ….
La classe DataFrameWriter
dispose des méthodes json,
csv, parquet pour persister les
données.
Le membre write de la
dataframe pointe sur un objet
de type DataFrameWriter.
Persister un DF
28. EXÉCUTER UNE REQUÊTE SQL SUR UN FICHIER SOURCE
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// Lancer une requête SQL sur un fichier json
val sqlJSON = spark.sql("SELECT * FROM json.`VotrePathSpark/people.json`")
// retour > sqlJSON: org.apache.spark.sql.DataFrame = [age: bigint, name: string]
// Lancer une requête SQL sur un fichier CSV
val sqlCSV = spark.sql("SELECT * FROM csv.`VotrePathSpark/people.txt`")
// retour > sqlCSV: org.apache.spark.sql.DataFrame = [_c0: string, _c1: string]
// Lancer une requête SQL sur un fichier parquet
val sqlParquet = spark.sql("SELECT * FROM parquet.`VotrePathSpark/users.parquet`")
// sqlParquet: org.apache.spark.sql.DataFrame = [name: string, favorite_color: string ... 1
more field]
Exemple
28
M.MICHRAFY
En Spark SQL, il est possible de
lancer une requête sur un
fichier de format JSON, CSV,
PARQUET, ….
Pour ce faire, il suffit d’utiliser
la méthode sql de la classe
sparkSession.
Requête SQL
29. TYPAGE D’UNE COLONNE D’UNE DATAFRAME
import org.apache.spark.sql.SparkSession // importer sparkSession
import org.apache.spark.sql.functions._ // pour la fonction udf
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
// Charger un fichier csv
val dfcsv = spark.read.csv("VotrePathSpark/people.txt").toDF("nom", "age")
// dfcsv: org.apache.spark.sql.DataFrame = [nom: string, age: string]
val toInt = udf[Int, String]( _.trim().toInt) // toInt : supprimer le blanc, et convertir en entier
// appliquer la fonction toInt sur la colonne age de dfcsv
val dft = dfcn.withColumn("age", toInt(dfcn("age")))
// dft: org.apache.spark.sql.DataFrame = [name: string, age: int]
Dft.printSchema // afficher le schema de la dataframe dft
root
|-- name: string (nullable = true)
|-- age: integer (nullable = true)
Exemple
29
M.MICHRAFY
En Spark SQL dispose des outils
pour accéder à une colonne
et typer ses valeurs
withColumn est une méthode
d’une dataSet permettant de
remplacer une colonne.
La fonction udf permet
d’appliquer une opération sur
les éléments d’une colonne.
Typage
30. DATAFRAME, CORRIGER LES DONNÉES
import org.apache.spark.sql.SparkSession // importer sparkSession
val spark = SparkSession .builder().getOrCreate() // Créer SparkSession
case class Personne(ville:String, nom:String, score:Double) // case classe
val x = Seq(Personne("Paris", "Stefan", 9), Personne("Lyon", "Alain", 15), Personne("Pariss",
null, 12)) // Créer une séquence de personnes
val dfx = spark.createDataFrame(x) // Créer une dataFrame via la séquence x
dfx.collect() // afficher le contenu de la dataframe dfx
// Array[org.apache.spark.sql.Row] = Array([Paris,Stefan,9.0], [Lyon,Alain,15], [Pariss,null,12.0])
// remplacer null de la colonne « nom » par inconnu en utilisant la fonction fill
Val dfy = dfx.na.fill(Map("nom" -> "inconnu"))
// remplacer « pariss » par « paris », colonne « ville »
val dfz = dfy.na.replace("ville", Map("Pariss" -> "Paris"))
dfz.show() // afficher le contenu de la dataframe dfz
|ville| nom|score|
|Paris| Stefan| 9.0|
| Lyon| Alain| 15 |
|Paris|inconnu| 12.0|
Exemple
30
M.MICHRAFY
DataFrameNaFunctions
permet de gérer les valeurs
manquantes d’une
dataFrame via les fonctions :
drop, fill, replace
na une méthode de la
DataFrame permet
d’accéder un objet de type
DataFrameNaFunctions.
Typage
31. RÉFÉRENCES
Guide de programmation Spark SQL (http://spark.apache.org/docs/2.0.2/sql-
programming-guide.html)
API SPARK, langage Scala (http://spark.apache.org/docs/2.0.2/api/scala/index.html)
Spark SQL: Relational Data Processing in Spark
(http://people.csail.mit.edu/matei/papers/2015/sigmod_spark_sql.pdf)
31