TP analyse de données (I)

Dans ce TP nous allons commencer par comparer un jeu de données qui concerne les univers DC et Marvel.
Ensuite, sujet plus sérieux, nous allons faire parler les données RÉELLES de Parcoursup ! 

Marvel VS DC

Lecture

Dans ce TP nous allons travailler avec un fichier csv.

Nous utiliserons le module csv de la bibliothèque standard. (standard = pas de pip install).

Commencez par un dossier TP_data ensuite, téléchargez le fichier suivant dans votre dossier TP_data :

Maintenant, dans le même dossier créez le fichier tp_data contenant le code suivant :

# On importe le moduele csv
import csv
# On charge le fichier csv
data = open("db.csv", newline='')
# On le lit et le transforme en liste.
table = list(csv.reader(data, delimiter=';'))
# On affiche cette liste
print(table) 

La fonction reader du module csv prend en argument un fichier ouvert et renvoie une valeur spéciale représentant un fichier CSV. Avec l’aide la  fonction list on convertie cela en tableau Python.

On remarque alors que la variable table contient un tableau de tableau de chaîne de caractères. Le première tableau contient :

['Id', 'Titre', 'Company',
    'Note', 'Score', 'Durée',
    'Sortie', 'Budget',
    "Weekend d'ouverture USA",
    'USA', 'Monde'] 

Ce premier tableau est important, il contient les descripteurs ou attributs.

Vous pouvez afficher un peu mieux vos données avec cette simple boucle :

for ligne in table:
    print(ligne) 

Quel est le contenu des variables table[1][1] et table[1][6], de quel type sont ces variables ?

‘Iron Man’ et ‘2008’. Les deux variables sont des chaînes de caractères.

Ceci dit, cette structure de donnée n’est pas de plus pratiques… Une alternative est proposée par le module csv, la fonction DictReader.

import csv
# On charge le fichier csv
data = open("db.csv", newline='')
# On le lit et le transforme en liste.
table = list(csv.DictReader(data, delimiter=';')) 

On obtient un tableau de dictionnaires ordonnés (Dans ces dictionnaires, les clés resteront dans l’ordre contrairement aux dictionnaires de base)

Pour accéder, par exemple à Iron man, on peut écrire : table[1]['Titre'] et l’année de sortie de ce film : table[1]['sortie']

Par contre, le type des données n’est pas celui qu’on souhaite, la date reste, par exemple, en string…  D’où l’exercice suivant :

Exercice

Écrivez une fonction qui prend en entrée un dictionnaire comme ceux dans notre table et qui retourne un dictionnaire mais avec les bons types et qui vérifie que la note est bien comprise en 0 et 10. Ensuite appliquer cette fonction à toutes les lignes de la table.

map et dic.get

def validation(ligne):
    """Prend en entrée une ligne de la table
    et en retourne une copie valide"""
    identifiant = int(ligne['Id'])
    titre = ligne['Titre']
    company = ligne['Company']
    note = float(ligne['Note']) # Entre 0 et 10
    if note > 10 or note < 0:
        exit("Note invalide dans le fichier")
    score = int(ligne['Score']) # Entre 0 et 100
    duree = int(ligne['Durée']) # en minute
    sortie = int(ligne['Sortie']) # en année
    budget = int(ligne['Budget']) #en dollar
    week = int(ligne["Weekend d'ouverture USA"])
    usa = int(ligne['USA'])
    monde = int(ligne['Monde'])
    return {'Id' : identifiant,
            'Titre' : titre,
            'Company' : company,
            'Note' : note,
            'Score' : score,
            'Durée' : duree,
            'Sortie' : sortie,
            'Budget' : budget,
            "Weekend d'ouverture USA" : week,
            'USA' : usa,
            'Monde' : monde
           } 

Maintenant appliquons cette fonction à chaque ligne.

table_valide = [validation(l) for l in table] 

Quelques remarques :

Déjà, nous avons décidé de faire une copie de la table, nous aurions très bien pu faire une validation “en place”, c’est à dire en modifiant la table originale.

Ici, on remarque que ligne[‘Score’] provoque une erreur si la clé score est absente du dictionnaire. Il existe une autre façon de faire : ligne.get('Score', 'pas de score') (https://www.tutorialspoint.com/python/dictionary_get.htm)

Et finalement, pour appliquer une fonction à chaque élément d’une liste il est pertinent d’avoir recours à map:

table_valide = list(map(validation, table)) 

Recherche

On souhaite interroger cette table et lui poser quelques questions, on appelle ces questions des requêtes.

Exercices

Écrivez une fonction present(titre, table) qui permet de vérifier si un film est présent dans notre table, la recherche effectue à partir du titre.

Votre fonction doit réussir le tests suivants :

assert present("Iron Man", table) == True, 'pourtant il est présent'
assert present("Daredevil", table) == False, 'il ne se trouve pas dans la table' 
def present(titre, bdd):  
    for film in bdd:
        if film['Titre'] == titre:
            return True
    return False 

Écrivez une requête qui permet de connaitre la note d’un film à partir de son titre.

def note(titre, bdd):    
    for film in bdd:
        if film['Titre'] == titre:
            return film['Note']
    return None  # Ligne facultative. 

Écrivez une requête qui retourne le titre des films sortie une année donnée.

Pour sortie_en(2018, table_valide) on attend :

['Black Panther', 'Avengers: Infinity War', 'Ant-Man and the Wasp', 'Aquaman'] 
def sortie_en(annee, bdd):
    reponse = []
    for film in bdd:
        print
        if film['Sortie'] == annee:
            reponse.append(film["Titre"])
    return reponse 

Écrivez une requête qui retourne la note moyenne des films de la table.

def moyenne(bdd):
    somme = 0
    for film in bdd:
        somme += film['Note']
    return round(somme / len(bdd), 1) 

round(nombre, n) permet d’arrondir à n chiffre après la virgule.
Écrivez une requête qui retourne le film ayant fait le meilleur Weekend d’ouverture aux USA.

def meilleur_weekend(bdd):
    maxi = 0
    for film in bdd:
        if film["Weekend d'ouverture USA"] > maxi:
            maxi = film["Weekend d'ouverture USA"]
            titre = film['Titre']
    return titre 

Écrivez une requête qui retourne la note moyenne d’une compagny donnée (Marvel ou DC). Comparer ces notes.

def marvel_vs_dc(bdd):
    dc = 0
    dc_somme = 0
    marvel =0
    marvel_somme = 0
    for film in bdd:
        if film['Company'] == 'Marvel':
            marvel += 1
            marvel_somme += film['Note']
        if film['Company'] == 'DC':
            dc += 1
            dc_somme += film['Note']
    return round(dc_somme / dc, 1), round(marvel_somme / marvel, 1) 

Sans surprise c’est Marvel qui l’emporte.

Analyse de données

 Dans cette partie nous utiliserons le module mathplotlib. Une introduction est disponible ici : https://codesturm.eu/2020/04/05/matplotlib/

L’objectif est de tracer quelques courbes pour faire apparaître certaines tendances.

Ici, il s’agit plus d’une démonstration de ce qu’on peut faire avec un jeu de données et la bibliothèque matplotlib

Voici un exemple permettant de comparer les budgets de Marvel et de DC.

from matplotlib import pyplot
dc = 0
marvel = 0
for film in table_valide:
    if film['Company'] == 'Marvel': 
        marvel += film['Budget']
    if film['Company'] == 'DC':
        dc += film['Budget']

pyplot.figure(figsize = (10, 10))
x = [marvel, dc]
pyplot.pie(x, labels = ['Marvel', 'DC'],
           colors = ['red', 'green'],
           explode = [0, 0],
           autopct = lambda x: str(round(x, 2)) + '%',
           pctdistance = 0.5, labeldistance = 0.4,
           shadow = True)
pyplot.title('Budget total')
pyplot.legend() 

Un autre exemple :

notes_marvel = []
notes_cd = []
for film in table_valide:
    if film['Company'] == 'Marvel': 
        notes_marvel.append(film['Note'])
    if film['Company'] == 'DC':
        notes_cd.append(film['Note'])
pyplot.title('Évolution des notes')

graphe1, = pyplot.plot(
    [i for i in range(len(notes_marvel))],
    notes_marvel,
    color = 'red',
    linewidth = 2,
    markerfacecolor = 'blue',
    markersize = 5
    )
graphe2, = pyplot.plot(
    [i for i in range(len(notes_cd))],
    notes_cd,
    color = 'blue',
    linewidth = 2,
    markerfacecolor = 'blue',
    markersize = 5
    )

# lable des axes
pyplot.xlabel('Films')
pyplot.ylabel('Notes')
#Affichage d'une légende
pyplot.legend([graphe1, graphe2], ['Marvel', 'DC'])
plt.grid()
plt.show() 

A vous d’imaginer comment représenter et exploiter ces données…
Dans un prochain TP nous travaillerons sur un jeu de données plus conséquent et nous ferons appel à pandas.

Parcoursup

Retour en haut
Retour haut de page