Environnement - Packages¶
In [3]:
# activation de l'environnement
using Pkg
Pkg.activate("./env_julia_query")
Activating project at `c:\Users\ricco\Desktop\demo\env_julia_query`
In [4]:
# lister les packages installés
Pkg.status()
Status `C:\Users\ricco\Desktop\demo\env_julia_query\Project.toml` [a93c6f00] DataFrames v1.8.2 [7073ff75] IJulia v1.34.4 [1a8c2f83] Query v1.1.0 [fdbf4ff8] XLSX v0.11.3
Package "Query" - Getting started¶
Chargement du dataframe "Fournisseurs"¶
In [5]:
# chargement des données (DataFrame)
import DataFrames as DFR
import XLSX
# lecture -> DataFrame
dfFour = DFR.DataFrame(XLSX.readtable("./fournisseurs.xlsx"))
println(DFR.first(dfFour,10))
10×5 DataFrame Row │ Num_fournisseur Societe Adresse Ville Pays │ Int64 String String String String ─────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 1 Exotic Liquids 49 Gilbert St. London Royaume-Uni 2 │ 2 Nouvelle-Orléans Cajun Delights P.O. Box 78934 Nouvelle-Orléans Etats-Unis 3 │ 3 Grandma Kelly's Homestead 707 Oxford Rd. Ann Arbor Etats-Unis 4 │ 4 Tokyo Traders 9-8 Sekimai Musashino-shi Tokyo Japon 5 │ 5 Cooperativa de Quesos 'Las Cabra… Calle del Rosal 4 Oviedo Espagne 6 │ 6 Mayumi's 92 Setsuko Chuo-ku Osaka Japon 7 │ 7 Pavlova, Ltd. 74 Rose St. Moonie Ponds Melbourne Australie 8 │ 8 Specialty Biscuits, Ltd. 29 King's Way Manchester Royaume-Uni 9 │ 9 PB Knäckebröd AB Kaloadagatan 13 Göteborg Suède 10 │ 10 Refrescos Americanas LTDA Av. das Americanas 12.890 São Paulo Brésil
Requêtes de type "dplyr" (mode "Standalone")¶
In [6]:
# importer le package
# utilisation de using pour accéder directement aux macros @...
using Query
# requête = enchaînement d'opérations sous forme de pipeline
# plutôt dans le style "dplyr" de R
# le résultat est typé en DataFrame
result = dfFour |>
@filter(_.Pays == "France") |>
@map({_.Societe,_.Ville}) |>
DFR.DataFrame
# affichage
println(result)
3×2 DataFrame Row │ Societe Ville │ String String ─────┼────────────────────────────────────── 1 │ Aux joyeux ecclésiastiques Paris 2 │ Escargots Nouveaux Montceau 3 │ Gai pâturage Annecy
Requêtes de type "LINQ"¶
In [7]:
# une autre manière d'écrire la même requête
# avec le formalisme LINQ
# "i" est in itérateur qui symbolise les lignes
result = @from i in dfFour begin
@where i.Pays == "France"
@select {i.Societe, i.Ville}
@collect DFR.DataFrame
end
# affichage
println(result)
3×2 DataFrame Row │ Societe Ville │ String String ─────┼────────────────────────────────────── 1 │ Aux joyeux ecclésiastiques Paris 2 │ Escargots Nouveaux Montceau 3 │ Gai pâturage Annecy
In [8]:
# ou mixée sous forme de pipeline
# attention, pas d'espace entre @query et la parenthèse !!!
# on se rapproche du SQL mais l'intérêt n'est pas ouf dans notre contexte
result = dfFour |>
@query(i, begin
@where i.Pays == "France"
@select {i.Societe, i.Ville}
end) |> DFR.DataFrame
# affichage
println(result)
3×2 DataFrame Row │ Societe Ville │ String String ─────┼────────────────────────────────────── 1 │ Aux joyeux ecclésiastiques Paris 2 │ Escargots Nouveaux Montceau 3 │ Gai pâturage Annecy
Requêtes de type LINQ mono-table¶
Filtrage¶
In [9]:
# filtrage avec tous les champs
result = @from i in dfFour begin
@where i.Pays == "Japon"
@select i
@collect DFR.DataFrame
end
# affichage
print(result)
2×5 DataFrame Row │ Num_fournisseur Societe Adresse Ville Pays │ Int64 String String String String ─────┼─────────────────────────────────────────────────────────────────────────── 1 │ 4 Tokyo Traders 9-8 Sekimai Musashino-shi Tokyo Japon 2 │ 6 Mayumi's 92 Setsuko Chuo-ku Osaka Japon
Projection¶
In [10]:
# projection sans filtrage
# avec renommage des champs
result = @from i in dfFour begin
@select {Society = i.Societe, City = i.Ville}
@collect DFR.DataFrame
end
# affichage
println(DFR.first(result,5))
5×2 DataFrame Row │ Society City │ String String ─────┼───────────────────────────────────────────────────── 1 │ Exotic Liquids London 2 │ Nouvelle-Orléans Cajun Delights Nouvelle-Orléans 3 │ Grandma Kelly's Homestead Ann Arbor 4 │ Tokyo Traders Tokyo 5 │ Cooperativa de Quesos 'Las Cabra… Oviedo
Champ calculé¶
In [11]:
# Requête avec champ calculé (via une concaténation)
result = @from i in dfFour begin
@select {
i.Societe,
Endroit = i.Pays * "__" * i.Ville
}
@collect DFR.DataFrame
end
# affichage
println(DFR.first(result,5))
5×2 DataFrame Row │ Societe Endroit │ String String ─────┼───────────────────────────────────────────────────────────────── 1 │ Exotic Liquids Royaume-Uni__London 2 │ Nouvelle-Orléans Cajun Delights Etats-Unis__Nouvelle-Orléans 3 │ Grandma Kelly's Homestead Etats-Unis__Ann Arbor 4 │ Tokyo Traders Japon__Tokyo 5 │ Cooperativa de Quesos 'Las Cabra… Espagne__Oviedo
In [12]:
# ou bien, écriture à la mode Julia
result = @from i in dfFour begin
@select {
i.Societe,
Endroit = "$(i.Pays)_et_$(i.Ville)"
}
@collect DFR.DataFrame
end
# affichage
println(DFR.first(result,5))
5×2 DataFrame Row │ Societe Endroit │ String String ─────┼─────────────────────────────────────────────────────────────────── 1 │ Exotic Liquids Royaume-Uni_et_London 2 │ Nouvelle-Orléans Cajun Delights Etats-Unis_et_Nouvelle-Orléans 3 │ Grandma Kelly's Homestead Etats-Unis_et_Ann Arbor 4 │ Tokyo Traders Japon_et_Tokyo 5 │ Cooperativa de Quesos 'Las Cabra… Espagne_et_Oviedo
In [13]:
# on peut aussi créer en amont la nouvelle variable
# avec la macro @let
result = @from i in dfFour begin
@let new_name = "$(i.Pays)_et_$(i.Ville)"
@select {
i.Societe,
Endroit = new_name
}
@collect DFR.DataFrame
end
# affichage
println(DFR.first(result,5))
5×2 DataFrame Row │ Societe Endroit │ String String ─────┼─────────────────────────────────────────────────────────────────── 1 │ Exotic Liquids Royaume-Uni_et_London 2 │ Nouvelle-Orléans Cajun Delights Etats-Unis_et_Nouvelle-Orléans 3 │ Grandma Kelly's Homestead Etats-Unis_et_Ann Arbor 4 │ Tokyo Traders Japon_et_Tokyo 5 │ Cooperativa de Quesos 'Las Cabra… Espagne_et_Oviedo
In [14]:
# nouveau champ que l'on peut utiliser dans le filtrage
result = @from i in dfFour begin
@let new_name = "$(i.Pays)_et_$(i.Ville)"
@where occursin("France",new_name)
@select {
i.Societe,
Endroit = new_name
}
@collect DFR.DataFrame
end
# affichage
println(result)
3×2 DataFrame Row │ Societe Endroit │ String String ─────┼──────────────────────────────────────────────── 1 │ Aux joyeux ecclésiastiques France_et_Paris 2 │ Escargots Nouveaux France_et_Montceau 3 │ Gai pâturage France_et_Annecy
Regroupement¶
In [15]:
# regroupement et comptage
# on a un equivalent de groupby
result = @from i in dfFour begin
@group i by i.Pays into g
@select {Country = key(g), Nombre = length(g)}
@collect DFR.DataFrame
end
# affichage
println(result)
16×2 DataFrame Row │ Country Nombre │ String Int64 ─────┼───────────────────── 1 │ Royaume-Uni 2 2 │ Etats-Unis 4 3 │ Japon 2 4 │ Espagne 1 5 │ Australie 2 6 │ Suède 2 7 │ Brésil 1 8 │ Allemagne 3 9 │ Italie 2 10 │ Norvège 1 11 │ France 3 12 │ Singapour 1 13 │ Danemark 1 14 │ Pays-Bas 1 15 │ Finlande 1 16 │ Canada 2
In [16]:
# regroupement et filtrage
result = @from i in dfFour begin
@group i by i.Pays into g
@where length(g) > 1
@select {Country = key(g), Nombre = length(g)}
@collect DFR.DataFrame
end
# affichage
println(result)
9×2 DataFrame Row │ Country Nombre │ String Int64 ─────┼───────────────────── 1 │ Royaume-Uni 2 2 │ Etats-Unis 4 3 │ Japon 2 4 │ Australie 2 5 │ Suède 2 6 │ Allemagne 3 7 │ Italie 2 8 │ France 3 9 │ Canada 2
In [17]:
# la requête n'a aucun sens, juste pour montrer la possibilité
# champ calculé = moyenne des numéros associés aux groupes
import Statistics as ST
result = @from i in dfFour begin
@group i by i.Pays into g
@where length(g) > 1
@select {Country = key(g), Nombre = length(g), Moyenne = ST.mean(g.Num_fournisseur)}
@collect DFR.DataFrame
end
# affichage
println(result)
9×3 DataFrame Row │ Country Nombre Moyenne │ String Int64 Float64 ─────┼────────────────────────────── 1 │ Royaume-Uni 2 4.5 2 │ Etats-Unis 4 10.0 3 │ Japon 2 5.0 4 │ Australie 2 15.5 5 │ Suède 2 13.0 6 │ Allemagne 3 12.0 7 │ Italie 2 20.0 8 │ France 3 24.3333 9 │ Canada 2 27.0
Tri¶
In [18]:
# trier selon un champ (nom du Pays)
result = @from i in dfFour begin
@orderby i.Pays
@select {i.Societe,i.Pays}
@collect DFR.DataFrame
end
# affichage
println(result)
29×2 DataFrame Row │ Societe Pays │ String String ─────┼──────────────────────────────────────────────── 1 │ Heli Süßwaren GmbH & Co. KG Allemagne 2 │ Plutzer Lebensmittelgroßmärkte AG Allemagne 3 │ Nord-Ost-Fisch Handelsgesellscha… Allemagne 4 │ Pavlova, Ltd. Australie 5 │ G'day, Mate Australie 6 │ Refrescos Americanas LTDA Brésil 7 │ Ma Maison Canada 8 │ Forêts d'érables Canada 9 │ Lyngbysild Danemark 10 │ Cooperativa de Quesos 'Las Cabra… Espagne 11 │ Nouvelle-Orléans Cajun Delights Etats-Unis 12 │ Grandma Kelly's Homestead Etats-Unis 13 │ Bigfoot Breweries Etats-Unis 14 │ New England Seafood Cannery Etats-Unis 15 │ Karkki Oy Finlande 16 │ Aux joyeux ecclésiastiques France 17 │ Escargots Nouveaux France 18 │ Gai pâturage France 19 │ Formaggi Fortini s.r.l. Italie 20 │ Pasta Buttini s.r.l. Italie 21 │ Tokyo Traders Japon 22 │ Mayumi's Japon 23 │ Norske Meierier Norvège 24 │ Zaanse Snoepfabriek Pays-Bas 25 │ Exotic Liquids Royaume-Uni 26 │ Specialty Biscuits, Ltd. Royaume-Uni 27 │ Leka Trading Singapour 28 │ PB Knäckebröd AB Suède 29 │ Svensk Sjöföda AB Suède
In [19]:
# trier selon un champ calculé
# et filter
result = @from i in dfFour begin
@group i by i.Pays into g
@let moyenne = ST.mean(g.Num_fournisseur)
@orderby descending(moyenne)
@where length(g) > 1
@select {Country = key(g), Nombre = length(g), Moyenne = moyenne}
@collect DFR.DataFrame
end
# affichage
println(result)
9×3 DataFrame Row │ Country Nombre Moyenne │ String Int64 Float64 ─────┼────────────────────────────── 1 │ Canada 2 27.0 2 │ France 3 24.3333 3 │ Italie 2 20.0 4 │ Australie 2 15.5 5 │ Suède 2 13.0 6 │ Allemagne 3 12.0 7 │ Etats-Unis 4 10.0 8 │ Japon 2 5.0 9 │ Royaume-Uni 2 4.5
Requêtes multi-tables (avec jointures)¶
In [20]:
# Chargement de la table Produits
dfProd = DFR.DataFrame(XLSX.readtable("./produits.xlsx"))
println(DFR.first(dfProd,10))
10×5 DataFrame Row │ Ref_produit Nom_produit Num_fournisseur Quantite_par_unite Prix_unitaire │ Int64 String Int64 String Float64 ─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 1 Chai 1 10 boîtes x 20 sacs 18.0 2 │ 2 Chang 1 24 bouteilles (1 litre) 19.0 3 │ 3 Aniseed Syrup 1 12 bouteilles (550 ml) 10.0 4 │ 4 Chef Anton's Cajun Seasoning 2 48 pots (6 onces) 22.0 5 │ 5 Chef Anton's Gumbo Mix 2 36 boîtes 21.35 6 │ 6 Grandma's Boysenberry Spread 3 12 pots (8 onces) 25.0 7 │ 7 Uncle Bob's Organic Dried Pears 3 12 cartons (1 kg) 30.0 8 │ 8 Northwoods Cranberry Sauce 3 12 pots (12 onces) 40.0 9 │ 9 Mishi Kobe Niku 4 18 cartons (500 g) 97.0 10 │ 10 Ikura 4 12 pots (200 g) 31.0
In [21]:
# nom de societe de fournisseur par produit
# avec une sorte de double boucle (pas optimal du tout)
# mais ça marche...
result = @from i in dfProd begin
@from j in dfFour
@where (i.Num_fournisseur == j.Num_fournisseur)
@select {i.Nom_produit,i.Num_fournisseur, j.Societe}
@collect DFR.DataFrame
end
# affichage
print(DFR.first(result,10))
10×3 DataFrame Row │ Nom_produit Num_fournisseur Societe │ String Int64 String ─────┼─────────────────────────────────────────────────────────────────────────────────── 1 │ Chai 1 Exotic Liquids 2 │ Chang 1 Exotic Liquids 3 │ Aniseed Syrup 1 Exotic Liquids 4 │ Chef Anton's Cajun Seasoning 2 Nouvelle-Orléans Cajun Delights 5 │ Chef Anton's Gumbo Mix 2 Nouvelle-Orléans Cajun Delights 6 │ Grandma's Boysenberry Spread 3 Grandma Kelly's Homestead 7 │ Uncle Bob's Organic Dried Pears 3 Grandma Kelly's Homestead 8 │ Northwoods Cranberry Sauce 3 Grandma Kelly's Homestead 9 │ Mishi Kobe Niku 4 Tokyo Traders 10 │ Ikura 4 Tokyo Traders
In [22]:
# avec la macro @join pour jointure
# autrement plus indiqué
result = @from i in dfProd begin
@left_outer_join j in dfFour on i.Num_fournisseur equals j.Num_fournisseur
@select {i.Nom_produit,i.Num_fournisseur, j.Societe}
@collect DFR.DataFrame
end
# affichage
print(DFR.first(result,10))
10×3 DataFrame Row │ Nom_produit Num_fournisseur Societe │ String Int64 String? ─────┼─────────────────────────────────────────────────────────────────────────────────── 1 │ Chai 1 Exotic Liquids 2 │ Chang 1 Exotic Liquids 3 │ Aniseed Syrup 1 Exotic Liquids 4 │ Chef Anton's Cajun Seasoning 2 Nouvelle-Orléans Cajun Delights 5 │ Chef Anton's Gumbo Mix 2 Nouvelle-Orléans Cajun Delights 6 │ Grandma's Boysenberry Spread 3 Grandma Kelly's Homestead 7 │ Uncle Bob's Organic Dried Pears 3 Grandma Kelly's Homestead 8 │ Northwoods Cranberry Sauce 3 Grandma Kelly's Homestead 9 │ Mishi Kobe Niku 4 Tokyo Traders 10 │ Ikura 4 Tokyo Traders
In [23]:
# liste des produits, dont le prix est > 50, et leurs fournisseurs
result = @from i in dfProd begin
@left_outer_join j in dfFour on i.Num_fournisseur equals j.Num_fournisseur
@where i.Prix_unitaire > 50
@select {i.Nom_produit, j.Societe, i.Prix_unitaire}
@collect DFR.DataFrame
end
# affichage
print(result)
7×3 DataFrame Row │ Nom_produit Societe Prix_unitaire │ String String? Float64 ─────┼─────────────────────────────────────────────────────────────────────────── 1 │ Mishi Kobe Niku Tokyo Traders 97.0 2 │ Carnarvon Tigers Pavlova, Ltd. 62.5 3 │ Sir Rodney's Marmalade Specialty Biscuits, Ltd. 81.0 4 │ Thüringer Rostbratwurst Plutzer Lebensmittelgroßmärkte AG 123.79 5 │ Côte de Blaye Aux joyeux ecclésiastiques 263.5 6 │ Manjimup Dried Apples G'day, Mate 53.0 7 │ Raclette Courdavault Gai pâturage 55.0
In [24]:
# prix moyen par fournisseur
# trié par ordre décroissant
result = @from i in dfFour begin
@join j in dfProd on i.Num_fournisseur equals j.Num_fournisseur
@group j.Prix_unitaire by i.Societe into g
@let avg_prix = ST.mean(g)
@orderby descending(avg_prix)
@select {Fournisseur = key(g), Prix_Moyen = avg_prix}
@collect DFR.DataFrame
end
# affichage
print(result)
29×2 DataFrame Row │ Fournisseur Prix_Moyen │ String Float64 ─────┼─────────────────────────────────────────────── 1 │ Aux joyeux ecclésiastiques 140.75 2 │ Tokyo Traders 46.0 3 │ Plutzer Lebensmittelgroßmärkte AG 44.678 4 │ Gai pâturage 44.5 5 │ Forêts d'érables 38.9 6 │ Pavlova, Ltd. 35.57 7 │ Grandma Kelly's Homestead 31.6667 8 │ G'day, Mate 30.9333 9 │ Heli Süßwaren GmbH & Co. KG 29.71 10 │ Cooperativa de Quesos 'Las Cabra… 29.5 11 │ Pasta Buttini s.r.l. 28.75 12 │ Specialty Biscuits, Ltd. 28.175 13 │ Leka Trading 26.4833 14 │ Formaggi Fortini s.r.l. 26.4333 15 │ Nord-Ost-Fisch Handelsgesellscha… 25.89 16 │ Nouvelle-Orléans Cajun Delights 20.35 17 │ Norske Meierier 20.0 18 │ Svensk Sjöföda AB 20.0 19 │ Karkki Oy 18.0833 20 │ Ma Maison 15.725 21 │ Exotic Liquids 15.6667 22 │ Bigfoot Breweries 15.3333 23 │ PB Knäckebröd AB 15.0 24 │ Mayumi's 14.9167 25 │ New England Seafood Cannery 14.025 26 │ Escargots Nouveaux 13.25 27 │ Zaanse Snoepfabriek 11.125 28 │ Lyngbysild 10.75 29 │ Refrescos Americanas LTDA 4.5