Analyse de données avec pandas

Dans ce TD nous allons utiliser la bibliothèque pandas pour analyser les données du répertoire GitHub https://github.com/in202-uvsq/git-manual avec lequel vous avez travaillé pour le contrôle continu.

Commencez par les lignes de configuration habituelles

In [1]:
%matplotlib inline

import pandas as pd

Nous allons commencer par importer des données statistiques sur les contributions par utilisateur par semaine. Les lignes qui suivent téléchargent les données de la BD de GitHub.

In [2]:
import urllib2, json, datetime
contr = json.load(urllib2.urlopen('https://api.github.com/repos/in202-uvsq/git-manual/stats/contributors'))

L'objet contr contient plein de données peu intéressantes. La cellule suivante fait le menage, en gardant uniquement cinq colonnes :

  • La semaine
  • Le nom de l'utilisateur
  • Le nombre de lignes ajoutés
  • Le nombre de lignes effacées
  • Le nombre de commits

La semaine est au format epoch : nombre de millisecondes depuis le premier janvier 1970. Elle est lue avec la fonction datetime.datetime.fromtimestamp().

In [3]:
data = [{ 'semaine' : datetime.datetime.fromtimestamp(w['w']).date(),
          'utilisateur' : c['author']['login'],
          'ajouts' : w['a'],
          'effacements' : w['d'],
          'commits' : w['c'] }
        for c in contr for w in c['weeks']]

Exercices

Affichez le contenu de l'objet data. Créez un DataFrame pandas à partir de data, comme ceci.

In [4]:
d = pd.DataFrame(data)
  1. Affichez le nombre total de commits (méthode .sum()).

  2. Affichez les statistiques sur les données (méthode .describe()). Quel est le nombre maximal d'ajouts effectués en une semaine par un utilisateur ?

Sélections

  1. Sélectionnez uniquement les lignes qui portent votre nom d'utilisateur (ou celui d'un de vos collègues, si aucun commit ne vous appartient). Affichez le résultat.

  2. Dessinnez le graphe de vos contributions par semaine. La méthode .plot() peut prendre un argument pour indiquer quelle colonne mettre en abscisse ; voir exemple ci-dessous.

  3. Trouvez l'utilisateur qui, sur une semaine, a fait le plus de

    • commits,
    • ajouts,
    • effacements.
In [5]:
# Exemple: choisir une colonne pour abscisse

e = pd.DataFrame({ 'espèce': [ 'chien', 'loup', 'chat' ],
                   'age' : [15, 10, 20] })
e.plot()
Out[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f6c03631490>
In [6]:
e.plot('espèce')
Out[6]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f6c02cf9f50>

Regrouper

  1. En utilisant la méthode .groupby, afficher le nombre total de commits, ajouts, effacements par semaine.
  2. En utilisant la méthode .groupby, afficher le nombre total de commits, ajouts, effacements par utilisateur.
  3. Trouver les cinq utilisateurs avec le plus d'ajouts (vous pouvez utiliser la méthode sort pour ordonner les données).
  4. Calculer la moyenne de commits par semaine de chaque utilisateur.

Jointures

La cellule suivante télécharge la liste de toutes les pull requests du projet.

In [7]:
pulls = json.load(urllib2.urlopen('https://api.github.com/repos/in202-uvsq/git-manual/pulls?state=all'))

On nettoye les données, pour garder uniquement

  • Le numéro de la pull request,
  • Son titre,
  • Son créateur,
  • Ses dates de création et de fermeture.

Les dates sont cette fois-ci au format ISO, par ex.: 2015-03-01. On les lit avec la fonction dateutil.parser.parse.

In [8]:
import dateutil.parser as parser

data = [{ 'numero' : p['number'],
          'titre' : p['title'],
          'utilisateur' : p['user']['login'],
          'creation' : parser.parse(p['created_at']),
          'fermeture' : parser.parse(p['closed_at']) }
        for p in pulls]

Exercices

  1. Créez un DataFrame à partir de ces données.
  2. On peut calculer la durée d'une pull request en faisant la différence des colonnes creation et fermeture. Ajouter une colonne duree au DataFrame contenant cette information.

Partez du DataFrame construit précédemment, regroupé par utilisateur et ré-indexé :

In [9]:
d.groupby('utilisateur').sum().reset_index()
Out[9]:
utilisateur ajouts commits effacements
0 Emaltard 126 5 104
1 Gruudu 34 2 24
2 Iwantaponey 534 21 340
3 KaneBoubacar 158 5 80
4 Lebataclan 329 20 319
5 LowD 112 7 11
6 Melanie13340 51 1 0
7 Mr-Nico-972 115 4 57
8 Nambrok 355 15 450
9 Ousam 181 6 75
10 Protosspaspris 25 2 1
11 SuzanneAir 367 20 334
12 ThomasBrebant 233 7 65
13 Ylen96 633 9 325
14 amendiI 479 20 137
15 calae91 434 6 4
16 defeo 118 1 0
17 ducks-skills 409 2 205
18 incognitomada 16 2 12
19 moumzy 86 2 6
20 pierre-cauletUVSQ 47 4 13
21 yobero 558 22 321
  1. Avec la méthode .merge, fusionnez ce dernier DataFrame avec les pulls requests.
  2. Regroupez par utilisateur et calculez la moyenne (méthode .mean()).
  3. Comparez la durée maximale des pull requests de l'utilisateurs le plus productif avec la durée maximale de l'utilisateur le moins productif.
  4. Ordonnez par nombre d'ajouts, et dessinnez la durée maximale des pull requests en fonction du nombre d'ajouts.
  5. Même chose pour la durée moyenne des pull requests (vous aurez besoin de la méthode .aggreate().

Exercice: des données un peu plus fines

La ligne suivante télécharge la liste de tous les commits

In [10]:
commits = json.load(urllib2.urlopen('https://api.github.com/repos/in202-uvsq/git-manual/commits'))
  1. Étudier le format des données, et en extraire

    • Le SHA,
    • La date du commit sans l'heure (utiliser datetime comme plus haut),
    • Le login du créateur.

    Construire un DataFrame à partir de ces données.

  2. Dessinner le graphe de vos contributions jour par jour.