1ère Générale NSI

 

Term. Générale NSI

 

Terminale STI2D SIN

Bts Ccst

Technico-commercial 3.0

[[{"text":"","title":"Fusion de tables"}],[{"text":"
Il est fréquent lorsque l'on travaille avec des données, et particulièrement avec des données tabulées, de se retrouver avec plusieurs jeux de données.
Une question que l'on peut se poser naturellement est comment combiner ces jeux de données en une seule table?
En effet, une fois ces données combinées en une seule table, nous pouvons réutiliser les opérations vues dans les séquences précédentes :\n- filtrage,\n- sélection de colonnes,\n- agrégation,\n- tri.
Nous allons voir qu'il existe plusieurs manière pour fusionner  des données en tables.
Selon l'opération que l'on souhaite effectuer, des précautions particulières sont à prendre pour ne pas introduire d'incohérence dans les données.
"},{"input":""}],[{"text":"
Une première opération naturelle est de vouloir mettre dans une même table les données de deux tables existantes. 
Par exemple, sur la plateforme des données publiques françaises, on peut trouver des fichiers CSV recensant les listes des prénoms d'enfants nés dans certaines villes,
https://www.data.gouv.fr/fr/datasets/prenoms-a-rennes/
pour chaque année entre 2007 et 2015.
Chaque année est stockée dans un fichier CSV propre :

prenoms2018.csv

prenom2017.csv

prenoms2016.csv 

Il est naturel de vouloir réunir tous ces jeux de données en un seul, pour former une seule grande table que l'on peut ensuite filtrer ou trier.
Cette opération a du sens car tous ces fichiers, et donc toutes les tables correspondantes, possèdent la même structure :\n- elles ont les memes attributs (en nom et en nombre)\n- les attributs de même nom sont du même type.
Pour notre exemple, ces attributs donnent l'année de naissance, le sexe, le prenom et le nombre d'enfants nés avec ce prénom.
anneeprenomsexenombre
2018ArthurMasculin59
2018GabrielMasculin55
2018AdèleFéminin48
2018LouisMasculin48
2018AliceFéminin47
\n\t\t\t\t\t\t\t\t\t\t\nChargeons les données des années 2017 et 2018, contenues dans les deux fichiers prenoms2017.csv et prenoms2018.csv.
Attention, n'oubliez pas de mettre les fichiers csv dans le même répertoire que votre programme python.

import csv\nf2017 = open(\"prenoms2017.csv\")\nf2018 = open(\"prenoms2018.csv\")\n\nt2017 = list(csv.DictReader(f2017))\nt2018 = list(csv.DictReader(f2018))\n\nprint(\"t2017=\",t2017)\nprint(\"t2018=\",t2017)\n

Ecrire et tester le code.
Les deux tables ayant les mêmes attributs, il est possible de les réunir en une seule table contenant toutes les valeurs.
Nous pouvons faire cela en utilisant l'opérateur + sur les tableaux, comme nous l'avons déja vu.
t1718 = t2017 + t2018\nprint(t1718)
Ajouter et tester le code ci-dessous.
Le tableau t21718 que l'on obtient est un nouveau tableau contenant les éléments de t2017 suivis des éléments de t2018.\n
Du point de vue de Python, cette opération est toujours autorisée entre deux tableaux quelconques. 

","title":"Réunion de tables"},{"input":""}],[{"text":"
Mais a-t-elle toujours un sens dans le cadre de tables de données?
Une manière d'approcher le problème est de considérer les opérations que nous connaissons sur les tables.
Prenons l'exemple de la sélection de lignes d'une table. Si l'on souhaite connaitre les prénoms de toutes les filles nées en 2017, on peut écrire le code suivant :
fille2017 = [ f for f in t2017 if f[\"sexe\"] == \"Féminin\" ]
print(\"fille2017=\",fille2017)

Ajouter et tester le code ci-dessous.
La même opération aura aussi du sens pour la table t2018, de même que sur la table t1718.

fille2018 = [ f for f in t2018 if f[\"sexe\"] == \"Féminin\" ]
fille1718 = [ f for f in t1718 if f[\"sexe\"] == \"Féminin\" ]
print(\"fille2018=\",fille2018)
print(\"fille1718=\",fille1718)
Ajouter et tester le code ci-dessous.

"},{"input":"","place":"Ecrire le résultat ici."}],[{"text":"
Si nous réunissons les tables t2017 et la table élèves introduite à la séquence précédente, alors nous aurons un problème pour effectuer cette opération.
f_eleves = open(\"eleves.csv\")\nt_eleves = list(csv.DictReader(f_eleves.csv))\n\nmauvaisetable = t2017 + t_eleves\n\ntest = [ f for f in mauvaisetable if f[\"sexe\"] == \"Féminin\" ]\n
Ajouter et tester le code ci-dessous.
Quel est le problème dans la fusion de ces 2 tables?
Comme on le voit, réunir les valeurs de deux tables est une opération légitime, à condition que les tables aient les mêmes attributs et des attributs de mêmes type.

"},{"input":"","place":"Ecrire le résultat ici."}],[{"text":"
Nous pouvons aller plus loin et considérer des tables ayant des attributs différents, mais au moins un attribut commun.
Pour cela, nous considérons de nouveaux nos élèves.
PrénomAnnéeNote 1Note 2Appréciation
Stéphane200012.59.4AB
Paul20031417B
Régis2002915TB
Bernard20015.512B
Franck19991614.5AB
Léon20041416TB
La table correspondant à ce tableau est la suivante :
t_eleves = [{'prenom': 'Stéphane', 'annee': 2000, 'note1': 12.5, 'note2': 9.4, 'appreciation': 'AB'}, {'prenom': 'Paul', 'annee': 2003, 'note1': 14.0, 'note2': 17.0, 'appreciation': 'B'}, {'prenom': 'Régis', 'annee': 2002, 'note1': 9.0, 'note2': 15.0, 'appreciation': 'TB'}, {'prenom': 'Bernard', 'annee': 2001, 'note1': 5.5, 'note2': 12.0, 'appreciation': 'B'}, {'prenom': 'Franck', 'annee': 1999, 'note1': 16.0, 'note2': 14.5, 'appreciation': 'AB'}, {'prenom': 'Léon', 'annee': 2004, 'note1': 14.0, 'note2': 16.0, 'appreciation': 'TB'}]

Il se trouve que parmi ces élèves, Léon, Paul et Bernard ont rendu un devoir maison Le professeur renseigne les notes dans une autre table.
PrénomNote 3
Léon12
Paul13
Bernard9
La table correspondant à ce tableau est la suivante :
t_note3 = [ {'prenom': 'Paul', 'note': 13.0},{'prenom': 'Bernard','note': 9.0},{'prenom': 'Léon' , 'note': 12.0}]
On souhaite maintenant éditer un relevé de note, c'est-à-dire une table donnant pour chaque élève qui a eu une note 3 son prénom, son année, la note 1, 2 et 3.
La première chose à faire est de créer une fonction qui, étant donnée une ligne de la table élèves et une ligne de la table note3, crée un nouveau dictionnaire représentant la ligne du résultat.\n
def fusion(e, n) :\n    return { \"prenom\" : e[\"prenom\"] , \"annee\":e[\"annee\"] , \"note1\" : e[\"note1\"] , \"note2\" : e[\"note2\"] , \"note3\":n[\"note\"]}\n\nprint(fusion(t_eleves[1],t_note3[0]))

Ecrire et tester le code ci-dessus.
Ici, on choisit d'ignorer la clé prénom du dictionnaire n car nous l'avons déja dans le dictionnaires e.
","title":"Opération de jointure"},{"input":""}],[{"text":"
L'algorithme de \"fusion de table\" que l'on souhaite appliquer est une double boucle for.
t = []    \nfor e in t_eleves:\n     for n in t_note3:\n         if e[\"prenom\"] == n[\"prenom\"] :\n             t.append(fusion(e , n))\n\nprint(t)
Ajouter et tester le code.
A l'issue de cette boucle, le tableau t contient les trois lignes avec les notes de Paul, Bernard et Léon.
Nous avons obtenu le résultat escompté mais nous pouvons le faire d'une autre manière, en utilisant une double compréhension de tableaux.
Cette opération est une extension de la compréhension simple qui itère sur toutes les cases d'un tableau.
t2 = [ fusion(e, n) for e in t_eleves for n in t_note3 if e[\"prenom\"] == n[\"prenom\"]]\nprint(t2)\n
Ajouter et tester le code ci-dessous.
La double compréhension for e in t_eleves for n in t_note3 produit toutes les paires (e, n) de lignes de la table t_eleves et de la table t_note3 et ne conserve que celles pour lesquelles les valeurs de l'attribut prenom sont les mêmes dans les deux lignes.
Cette opération de mise en correspondance des lignes de deux tables ayant un attribut commun est appelée jointure de deux tables.
"},{"input":"","place":"Ecrire le résultat ici."}],[{"text":"
La double compréhension est un outil très puissant dans la gestion des données tabulées.
Par exemple, si on considère de nouveau nos deux tables des prénoms de 2017 et 2018, on peut calculer la nouvelle table suivante:
f2017 = open(\"prenoms2017.csv\")\nf2018 = open(\"prenoms2018.csv\")\n\nt2017 = list(csv.DictReader(f2017))\nt2018 = list(csv.DictReader(f2018))\n\nevolution = [{ \"PRN\" : t1[\"prenom\"] , \"NBR2017\" : int(t1[\"nombre\"]) , \\\n    \"NBR2018\" : int(t2[\"nombre\"]) } for t1 in t2017 for t2 in t2018 \\\n        if t1[\"prenom\"] == t2[\"prenom\"] ]\n    \nprint(evolution)\n
Ecrire et tester le code.
On obtient la table evolution contenant, pour chaque prenom, le nombre de naissances correspondantes en 2017 et en 2018, ce qui nous permettra de calculer la variation sur une annee pour un prénom donnée.

"},{"input":"","place":"Ecrire ici le résultat."}],[{"text":"
Lors de la production du relevé de notes ou de la variation des prénoms dans les partie précédente, nous avons fait une hypothèse implicite, à savoir que les prénoms étalent uniques.
Celle-ci est vraie pour les fichiers prenoms2017.csv et prenoms2018.csv mais pas pour la table élève suivante :
t_eleves = [{'prenom': 'Stéphane', 'annee': 2000, 'note1': 12.5, 'note2': 9.4, 'appreciation': 'AB'}, {'prenom': 'Paul', 'annee': 2003, 'note1': 14.0, 'note2': 17.0, 'appreciation': 'B'}, {'prenom': 'Régis', 'annee': 2002, 'note1': 9.0, 'note2': 15.0, 'appreciation': 'TB'}, {'prenom': 'Bernard', 'annee': 2001, 'note1': 5.5, 'note2': 12.0, 'appreciation': 'B'}, {'prenom': 'Franck', 'annee': 1999, 'note1': 16.0, 'note2': 14.5, 'appreciation': 'AB'}, {'prenom': 'Léon', 'annee': 2004, 'note1': 14.0, 'note2': 16.0, 'appreciation': 'TB'}, {'prenom': 'Paul', 'annee': 2005, 'note1': 9.0, 'note2': 11.0, 'appreciation': 'AB'}]\n


Supposons que l'élève Paul de l'année 2006 à une nouvelle note. Le professeur met sa note dans une table.\n
t_note4 = 
t_note4 = [{'prenom': 'Paul', 'note': 13.0}]
Si nous calculons la jointure entre la table t_note4 ci-dessus et la table t_eleves, nous obtenons la table suivante:
def fusion(e, n) :\n    return { \"prenom\" : e[\"prenom\"] , \"annee\":e[\"annee\"] , \"note1\" : e[\"note1\"] , \"note2\" : e[\"note2\"] , \"note3\":n[\"note\"]}\n\nt3 = [ fusion(e, n) for e in t_eleves for n in t_note4 if e[\"prenom\"] == n[\"prenom\"]]\nprint(t3)\n

Ajouter et tester le vode..

Il y a un problème. En effet, le prénom Paul n'étant pas unique dans la table élèves, le test interne if e[pronom\"] == n[\"prenom\"] est vrai deux fois.


","title":"Utilisation d'un identifiant unique"},{"input":"","place":"Ecrire le résulrar ici."}],[{"text":"
La situation précédente n'est pas satisfaisante. De manière générale, il est possible que des données \"réalistes\" ne suffisent pas à identifier des éléments de manière unique.
Par exemple, beaucoup de personnes portent le même nom et le même prénom. A l'échelle d'une ville, il est même courant que plusieurs personnes portent le même nom et aient la même date de naissance.
Pour prendre un autre exemple, les livres publiés sont identifiés par leur ISBN, un numéro unique attribué en France par l'AFNIL (Agence Francophone pour la Numérotation Internationale du Livre). On pourrait imaginer que l'ISBN est unique. Cependant, une bibliothèque qui possèderait plusieurs exemplaires d'un même ouvrage ne peut pas se fier uniquement à l'ISBN pour déterminer si un exemplaire particulier à été emprunté (elle peut en revanche lui associer un numéro d'inventaire unique). Comme on le voit, il est important de pouvoir associer un identifiant unique à chaque ligne d'une table car les données elles-mêmes ne permettent pas forcément de distinguer deux entrées de la table.
Une manière de faire est d'associer, au moment du chargement, un entier unique pour chaque entrée de la table.\n

Le code est le suivant pour ajouter un entier unique à chaque élève.
compteur = 0\nfor e in t_eleves:\n     e[\"id\"] = compteur\n     compteur = compteur + 1\n\nprint(t_eleves)\n\n
Ajouter et tester le code ci-dessous.
Ce code relativement compact modifie en place tous les enregistrements de la table chargee, en leur ajoutant un attribut id dont la valeur est un entier incrémenté a chaque ligne. Cet incrément permet d'assurer l'unicité de l'identifiant. On obtiendra donc la table suivante :
idPrénomAnnéeNote 1Note 2Appréciation
0Stéphane200012.59.4AB
1Paul20031417B
2Régis2002915TB
3Bernard20015.512B
4Franck19991614.5AB
5Léon20041416TB
5Paul2005911AB
La jointure peut alors se faire sur l'attribut id et en modifiant lq tqble t_note4 en t_note5. De cette manière le prénom est remplacé par l'id unique.
t_note5 = [{'id': 6 , 'note': 13.0}]\n\ndef fusionid(e, n) :\n    return { \"id\" : e[\"id\"] , \"prenom\" : e[\"prenom\"] , \"annee\":e[\"annee\"] , \"note1\" : e[\"note1\"] , \"note2\" : e[\"note2\"] , \"note3\":n[\"note\"]}\n\nt4 = [ fusionid(e, n) for e in t_eleves for n in t_note5 if e[\"id\"] == n[\"id\"]]\n
print(t4)\n
Ajouter et tester le code.

Donc en procédant de cette manière, nous avons uniquement modifié la note de Paul 2005. 
Attention la fonction fusion a été  modifiee en fusionid pour reporter l'attribut id dans le nouveau dictionnaire.\n

"},{"input":"","place":"Ecrire le résulrar ici. "}],[{"text":"
MembreLivre
idmPrénomidlTitreN° ISBN
0Stéphane12Le rouge et le noir9780736618137
1Paul16Madame de Bovary9782743431839
2Régis25Notre-Dame de Paris9781720460282
3Bernard26Notre-Dame de Paris9781720460282
34Les Misérables9781522998518
57Un aventurier de la liberté9782234086104
67Un monde sans fin9780451980267
Prêt
idpidmidl
0216
1026
2167
3357
4212
5225
On considère les tables ci-dessus Membre, Prêt et Livre. 
Déterminer à la main :\n- la jointure des tables Membre et Prêt;\n- la jointure des tables Prêt et Livre;\n
- la jointure des tables Menbre et Livre;
\n

","title":"Exercice 1"},{"input":""}],[{"text":"
Pour chaque table de l'exercice 1 écrire le contenu du fichier CSV. correspondant:
membre.csv\nlivre.csv\npret.csv
","title":"Exercice 2"},{"input":""}],[{"text":"
Ecrire un programme Python qui charge les trois fichiers membre.csv, pret.csv et livre.csv et qui mets les données dans 3 table :\nt_membre\nt_livre\nt_pret
","title":"Exercice 3"},{"input":"","place":"Ecrire le résultat ici."}],[{"text":"
Ecrire un programme Python qui réalise la jointure entre la table membre et prêt.
Faire de même pour la table prêt et livre.
","title":"Exercice 4"},{"input":"","place":"Ecrire le résultat ici."}],[{"text":"Ecrire le programme Python qui réalise la jointure entre la table membre et la table livre.
Ensuite celui-ci enregistre cette jointure dans le fichier resultat.csv . 
","title":"Exercice 5"},{"input":"","place":"Ecrire le résultat ici."}]]

En poursuivant votre navigation sur mon site, vous acceptez l’utilisation des Cookies et autres traceurs  pour réaliser des statistiques de visites et enregistrer sur votre machine vos activités pédagogiques. En savoir plus.