td3a correction session7az



Documents pareils
pyensae StockPrices September 1, Manipulation de séries financières avec la classe StockPrices

2015 kmeans. September 3, 2015

Big Data. Cyril Amsellem Consultant avant-vente. 16 juin Talend

Anticiper et prédire les sinistres avec une approche Big Data

Cours 1 : Introduction Ordinateurs - Langages de haut niveau - Application

Conventions d écriture et outils de mise au point

Cours 1 : La compilation

Big Data Concepts et mise en oeuvre de Hadoop

HAUTE DISPONIBILITÉ DE MACHINE VIRTUELLE AVEC HYPER-V 2012 R2 PARTIE CONFIGURATION OPENVPN SUR PFSENSE

Java et les bases de données

Ricco Rakotomalala R.R. Université Lyon 2

La technologie Java Card TM

Exercices types Algorithmique et simulation numérique Oral Mathématiques et algorithmique Banque PT

Java et les bases de données: JDBC: Java DataBase Connectivity SQLJ: Embedded SQL in Java. Michel Bonjour

OpenPaaS Le réseau social d'entreprise

Déploiement d une architecture Hadoop pour analyse de flux. françois-xavier.andreu@renater.fr

Tp 1 correction. Structures de données (IF2)

Les journées SQL Server 2013

Direction des Systèmes d'information

1. Structure d'un programme FORTRAN 95

SEMIN. Données sous R : stockage et échange. Julio PEDRAZA ACOSTA

Comment reproduire les résultats de l article : POP-Java : Parallélisme et distribution orienté objet

Imprimantes et partage réseau sous Samba avec authentification Active Directory

L écosystème Hadoop Nicolas Thiébaud Tuesday, July 2, 13

Approche Contract First

27/11/12 Nature. SDK Python et Java pour le développement de services ACCORD Module(s)

Sommaire. 3. Les grands principes de GFS L architecture L accès de fichier en lecture L accès de fichier en écriture Bilan

Le langage C. Séance n 4

Attaques applicatives

MapReduce. Malo Jaffré, Pablo Rauzy. 16 avril 2010 ENS. Malo Jaffré, Pablo Rauzy (ENS) MapReduce 16 avril / 15

Introduction à MATLAB R

Présentation Windows Azure Hadoop Big Data - BI

1 Description générale de VISFIELD

Django et PostgreSQL sous la charge

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

Licence Sciences et Technologies Examen janvier 2010

Petit guide pour l installation de CVW sous Linux

Flexible Identity. authentification multi-facteurs. authentification sans token. Version 1.0. Copyright Orange Business Services mai 2014.

Protection des protocoles

STAGE IREM 0- Premiers pas en Python

Cassandra et Spark pour gérer la musique On-line

Chapitre 10 Mettre en œuvre un cluster Hadoop

Bases Java - Eclipse / Netbeans

Les technologies du Big Data

Introduction aux Machines Virtuelles avec VMKit

Exemple d application: l annuaire DNS Claude Chaudet

Programmation Web. Madalina Croitoru IUT Montpellier

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Supervision et infrastructure - Accès aux applications JAVA. Document FAQ. Page: 1 / 9 Dernière mise à jour: 15/04/12 16:14

Quelques éléments de compilation en C et makefiles

Programmation C. Apprendre à développer des programmes simples dans le langage C

TP 1. Prise en main du langage Python

1 Lecture de fichiers

WDpStats Procédure d installation

modules & compilation

NFA 008. Introduction à NoSQL et MongoDB 25/05/2013

A.-M. Cubat PMB - Import de lecteurs - Généralités Page 1 Source :

Utilisation d objets : String et ArrayList

Gestion Electronique de Document (ECM/GED)

Hadoop, Spark & Big Data 2.0. Exploiter une grappe de calcul pour des problème des données massives

Open Source Job Scheduler. Installation(s)

1 Modélisation d être mauvais payeur

Annexe : La Programmation Informatique

«Cachez-moi cette page!»

API ONE-TIME PASSWORD

BASE. Vous avez alors accès à un ensemble de fonctionnalités explicitées ci-dessous :

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

La dernière base de données de Teradata franchit le cap du big data grâce à sa technologie avancée

Table des matières PRESENTATION DU LANGAGE DS2 ET DE SES APPLICATIONS. Introduction

Déploiement OOo en environnement Windows Terminal Server

Représentation d un entier en base b

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Gestion centralisée d un réseau de sites discrets. Nicolas JEAN

Formation Cloudera Data Analyst Utiliser Pig, Hive et Impala avec Hadoop

Slony1 2.1 Londiste 3

DEMARRER UN PROJET BIGDATA EN QUELQUES MINUTES GRACE AU CLOUD

V- Manipulations de nombres en binaire

Olivier Mondet

L3 informatique TP n o 2 : Les applications réseau

Skype (v2.5) Protocol Data Structures (French) Author : Ouanilo MEDEGAN

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

UE Programmation Impérative Licence 2ème Année

4 Exemples de problèmes MapReduce incrémentaux

Guide de démarrage Intellipool Network Monitor

Java DataBaseConnectivity

Génération de code binaire pour application multimedia : une approche au vol

TP, première séquence d exercices.

VTX FTP. Transfert de fichiers business par FTP - Manuel de l'utilisateur. Informations complémentaires : info@vtx.

Introduction à MapReduce/Hadoop et Spark

TP JAVASCRIPT OMI4 TP5 SRC

INFO-F-404 : Techniques avancées de systèmes d exploitation

Nouveautés Ignition v7.7

Guide Enseignant de l application OpenERP

1 - Introduction : Déroulement du déploiement avec WDS / MDT :

Support de TD ArcGIS Introduction à l automatisation et au développement avec ArcGIS 10.1 JEAN-MARC GILLIOT e année ingénieur

INTRODUCTION. Bienvenue dans la TCN FRENCH TEAM, nous allons ensemble démarrer une belle aventure qui peut devenir lucrative pour tous.

Télécom Nancy Année

Hadoop / Big Data. Benjamin Renaut <renaut.benjamin@tokidev.fr> MBDS

Transcription:

td3a correction session7az August 19, 2015 1 Séance 7 : PIG et JSON et streaming avec les données vélib (correction avec Azure) Plan Récupération des données Connexion au cluster et import des données Exercice 1 : convertir les valeurs numériques Exercice 2 : stations fermées Exercice 3 : stations fermées, journée complète Exercice 4 : astuces Récupération Connexion Exo 1 Exo2 Exo3 Astuces 1.1 Récupération des données In [1]: import pyensae import os, datetime In [2]: if not os.path.exists("velib") : os.mkdir("velib") files=pyensae.download_data("data_velib_paris_2014-11-11_22-23.zip", website="xdtd", whereto="ve files[:2] Out[2]: [ velib\\paris.2014-11-11 22-00-18.331391.txt, velib\\paris.2014-11-11 22-01-17.859194.txt ] 1.2 Connexion au cluster et import des données In [4]: import pyquickhelper, pyensae params={"blob_storage":"", "password1":"", "hadoop_server":"", "password2":"", "username":"alias pyquickhelper.open_html_form(params=params,title="server + hadoop + credentials", key_save="blob Out[4]: <IPython.core.display.HTML at 0xb28f810> In [1]: import pyensae blobstorage = blobhp["blob_storage"] blobpassword = blobhp["password1"] hadoop_server = blobhp["hadoop_server"] hadoop_password = blobhp["password2"] username = blobhp["username"] client, bs = %hd_open client, bs 1

Out[1]: (<pyensae.remote.azure connection.azureclient at 0x7f82430>, <azure.storage.blobservice.blobservice at 0xaad3a50>) On uploade les données (sauf si vous l avez déjà fait une fois) : In [3]: files = [ os.path.join("velib",_) for _ in os.listdir("velib") if ".txt" in _] In [4]: #client.upload(bs, "hdblobstorage", "velib_1h1", files) In [5]: df=%blob_ls hdblobstorage/velib_1h1 df.head() Out[5]: name \ 0 velib 1h1/paris.2014-11-11 22-00-18.331391.txt 1 velib 1h1/paris.2014-11-11 22-01-17.859194.txt 2 velib 1h1/paris.2014-11-11 22-02-17.544368.txt 3 velib 1h1/paris.2014-11-11 22-03-17.229557.txt 4 velib 1h1/paris.2014-11-11 22-04-18.204200.txt last modified content type content length \ 0 Tue, 25 Nov 2014 21:28:03 GMT application/octet-stream 523646 1 Tue, 25 Nov 2014 21:28:10 GMT application/octet-stream 523470 2 Tue, 25 Nov 2014 21:28:18 GMT application/octet-stream 522057 3 Tue, 25 Nov 2014 21:28:25 GMT application/octet-stream 523165 4 Tue, 25 Nov 2014 21:28:32 GMT application/octet-stream 523039 blob type 0 BlockBlob 1 BlockBlob 2 BlockBlob 3 BlockBlob 4 BlockBlob 1.3 Exercice 1 : convertir les valeurs numériques Le programme suivant prend comme argument les colonnes à extraire des fichiers textes qui sont enregistrés au format python. Le streaming sur Azure est sensiblement différent du streaming présenté avec Cloudera. Cette version fonctionne également avec Cloudera. La réciproque n est pas vraie. Les scripts python sont interprétés avec la machine virtuelle java tout comme pig. La solution suivante s inspire de Utilisation de Python avec Hive et Pig dans HDInsight. Voir également Writing Jython UDFs. Cette écriture impose de comprendre la façon dont PIG décrit les données et l utilisation de schema. Le nom du script doit être jython.py pour ce notebook sinon le compilateur PIG ne sait pas dans quel langage interpréter ce script. La version de jython utilisée sur le cluster est 2.5.3 (2.5:c56500f08d34+, Aug 13 2012, 14:54:35) [OpenJDK 64-Bit Server VM (Azul Systems, Inc.)]. La correction inclut encore un bug mais cela devrait être bientôt corrigé. Cela est dû aux différences Python/Jython. In [6]: import pyensae In [87]: %%PYTHON jython.py import datetime, sys, re @outputschema("brow: {(available_bike_stands:int, available_bikes:int, lat:double, lng:double, def extract_columns_from_js(row): 2

# pour un programmeur python, les schéma sont contre plut^ot intuitifs, # { } veut dire une liste, # ( ) un tuple dont chaque colonne est nommé # j écrirai peut-^etre une fonction détermine le schéma en fonction des données # il faut utiliser des expressions régulières pour découper la ligne # car cette expression ne fonctionne pas sur des lignes trop longues # eval ( row ) --> revient à évaluer une ligne de 500 Ko # Hadoop s arr^ete sans réellement proposer de message d erreurs qui mettent sur la bonne vo # dans ces cas-là, il faut relancer le job après avoir commenter des lignes # jusqu à trouver celle qui provoque l arr^et brutal du programme # arr^et qui ne se vérifie pas en local cols = ["available_bike_stands","available_bikes","lat","lng","name","status"] exp = re.compile ("(\\{.*?\\})") rec = exp.findall(row) res = [] for r in rec : station = eval(r) vals = [ str(station[c]) for c in cols ] res.append(tuple(vals)) return res La vérification qui suit ne fonctionne que si la fonction à tester prend comme entrée une chaîne de caractères mais rien n empêche de de créer une telle fonction de façon temporaire juste pour vérifier que le script fonctionne (avec Jython 2.5.3) : In [88]: %%jython jython.py extract_columns_from_js [{ address : RUE DES CHAMPEAUX (PRES DE LA GARE ROUTIERE) - 93170 BAGNOLET, collect_date : d [{ address : RUE DES CHAMPEAUX (PRES DE LA GARE ROUTIERE) - 93170 BAGNOLET, collect_date : d Out[88]: <IPython.core.display.HTML at 0xc1abcb0> On écrit le script PIG qui utilise plus de colonnes : In [4]: %%PIG json_velib_python.pig REGISTER $CONTAINER/$SCRIPTPIG/jython.py using jython as myfuncs; jspy = LOAD $CONTAINER/velib_1h1/*.txt USING PigStorage( \t ) AS (arow:chararray); DESCRIBE jspy ; matrice = FOREACH jspy GENERATE myfuncs.extract_columns_from_js(arow); DESCRIBE matrice ; multiply = FOREACH matrice GENERATE FLATTEN(brow) ; DESCRIBE multiply ; STORE multiply INTO $CONTAINER/$PSEUDO/velibpy_results/firstjob USING PigStorage( \t ) ; On supprime la précédente exécution si besoin puis on vérifie que le répertoire contenant les résultats est vide : In [5]: if client.exists(bs, client.account_name, "$PSEUDO/velibpy_results/firstjob"): r = client.delete_folder (bs, client.account_name, "$PSEUDO/velibpy_results/firstjob") print(r) 3

[ xavierdupre/velibpy results/firstjob, xavierdupre/velibpy results/firstjob/ SUCCESS, xavierdupre/ve In [6]: %hd_pig_submit json_velib_python.pig jython.py -stop_on_failure Out[6]: { id : job 1416874839254 0095 } In [9]: st = %hd_job_status job_1416874839254_0095 st["id"],st["percentcomplete"],st["status"]["jobcomplete"] Out[9]: ( job 1416874839254 0095, 100% complete, True) On récupère l erreur : In [10]: %tail_stderr job_1416874839254_0095 10 Out[10]: <IPython.core.display.HTML at 0xaa9fff0> In [11]: %blob_ls /$PSEUDO/velibpy_results Out[11]: name \ 0 xavierdupre/velibpy results 1 xavierdupre/velibpy results/firstjob 2 xavierdupre/velibpy results/firstjob/ SUCCESS 3 xavierdupre/velibpy results/firstjob/part-m-00000 last modified content type content length \ 0 Thu, 27 Nov 2014 08:56:03 GMT application/octet-stream 0 1 Thu, 27 Nov 2014 22:39:39 GMT 0 2 Thu, 27 Nov 2014 22:39:39 GMT application/octet-stream 0 3 Thu, 27 Nov 2014 22:39:39 GMT application/octet-stream 4693699 blob type 0 BlockBlob 1 BlockBlob 2 BlockBlob 3 BlockBlob On récupère les informations qu on affiche sous forme de dataframe : In [12]: if os.path.exists("velib_exo1.txt") : os.remove("velib_exo1.txt") %blob_downmerge /$PSEUDO/velibpy_results/firstjob velib_exo1.txt Out[12]: velib exo1.txt In [13]: %head velib_exo1.txt Out[13]: <IPython.core.display.HTML at 0xaa9fb70> In [14]: import pandas df = pandas.read_csv("velib_hd.txt", sep="\t",names=["available_bike_stands","available_bikes", df.head() Out[14]: available bike stands available bikes lat lng \ 0 47 3 48.864528 2.416171 1 5 28 48.872420 2.348395 2 42 1 48.882149 2.319860 3 5 31 48.868217 2.330494 4 20 5 48.893269 2.412716 4

name status 0 31705 - CHAMPEAUX (BAGNOLET) OPEN 1 10042 - POISSONNIÈRE - ENGHIEN OPEN 2 08020 - METRO ROME OPEN 3 01022 - RUE DE LA PAIX OPEN 4 35014 - DE GAULLE (PANTIN) OPEN 1.4 Exercice 2 : stations fermées Les stations fermées ne le sont pas tout le temps. On veut calculer le ratio minutes/stations fermées / total des minutes/stations. Le script python permettant de lire les données ne change pas, il suffit juste de déclarer les sorties numériques comme telles. Quelques détails sur les tables : jspy : contient les données brutes dans une liste de fichiers matrice : d après le job qui précède, la table contient une ligne par stations et par minute, chaque ligne décrit le status de la station grstation : table matrice groupée par status fermees : pour chaque groupe, on aggrégé le nombre de minutes multipliés par le nombre de vélos gr*,dist* : distribution du nombre de stations (Y) en fonction du nombre de vélos ou places disponibles En cas d exécution précédentes : In [122]: for sub in [ "multiply.txt"]: if client.exists(bs, client.account_name, "$PSEUDO/velibpy_results/" + sub): r = client.delete_folder (bs, client.account_name, "$PSEUDO/velibpy_results/" + sub) print(r) [ xavierdupre/velibpy results/fermees.txt ] [ xavierdupre/velibpy results/distribution bikes.txt ] [ xavierdupre/velibpy results/distribution stands.txt ] On va exécuter le job en deux fois. Le premier job met tout à plat. Le second calcule les aggrégations. La plupart du temps, le travaille de recherche concerne la seconde partie. Mais si le job n est pas scindé, la première partie est toujours exécutée à chaque itération. Dans ce cas-ci, on scinde le job en deux. La première partie forme une table à partir des données initiales. La seconde les agrègre. In [155]: %%PIG json_velib_python2.pig REGISTER $CONTAINER/$SCRIPTPIG/jython.py using jython as myfuncs; jspy = LOAD $CONTAINER/velib_1h1/*.txt USING PigStorage( \t ) AS (arow:chararray); DESCRIBE jspy ; matrice = FOREACH jspy GENERATE myfuncs.extract_columns_from_js(arow); DESCRIBE matrice ; multiply = FOREACH matrice GENERATE FLATTEN(brow) ; DESCRIBE multiply ; STORE multiply INTO $CONTAINER/$PSEUDO/velibpy_results/multiply.txt USING PigStorage( \t ) ; In [156]: %hd_pig_submit json_velib_python2.pig jython.py -stop_on_failure 5

Out[156]: { id : job 1416874839254 0125 } In [163]: st = %hd_job_status job_1416874839254_0125 st["id"],st["percentcomplete"],st["status"]["jobcomplete"] Out[163]: ( job 1416874839254 0125, 100% complete, True) In [165]: %blob_ls /$PSEUDO/velibpy_results/multiply.txt Out[165]: name \ 0 xavierdupre/velibpy results/multiply.txt 1 xavierdupre/velibpy results/multiply.txt/ SUCCESS 2 xavierdupre/velibpy results/multiply.txt/part-... last modified content type content length \ 0 Fri, 28 Nov 2014 01:46:41 GMT 0 1 Fri, 28 Nov 2014 01:46:41 GMT application/octet-stream 0 2 Fri, 28 Nov 2014 01:46:41 GMT application/octet-stream 4693699 blob type 0 BlockBlob 1 BlockBlob 2 BlockBlob In [167]: for sub in ["fermees.txt", "distribution_bikes.txt", "distribution_stands.txt"]: if client.exists(bs, client.account_name, "$PSEUDO/velibpy_results/" + sub): r = client.delete_folder (bs, client.account_name, "$PSEUDO/velibpy_results/" + sub) print(r) [ xavierdupre/velibpy results/fermees.txt, xavierdupre/velibpy results/fermees.txt/ temporary, xavier [ xavierdupre/velibpy results/distribution bikes.txt, xavierdupre/velibpy results/distribution bikes.tx [ xavierdupre/velibpy results/distribution stands.txt, xavierdupre/velibpy results/distribution stands. In [168]: %%PIG json_velib_python3.pig multiply = LOAD $CONTAINER/$PSEUDO/velibpy_results/multiply.txt USING PigStorage( \t ) AS (available_bike_stands:int, available_bikes:int, lat:double, lng:double, name:chararra DESCRIBE multiply ; grstation = GROUP multiply BY status ; DESCRIBE grstation ; fermees = FOREACH grstation GENERATE group,sum(multiply.available_bikes) AS available_bikes,sum(multiply.available_bike_stands) AS available_bike_stands ; DESCRIBE fermees ; gr_av = GROUP multiply BY available_bikes ; DESCRIBE gr_av; dist_av = FOREACH gr_av GENERATE group, COUNT(multiply) ; DESCRIBE dist_av; gr_pl = GROUP multiply BY available_bike_stands ; 6

DESCRIBE gr_pl; dist_pl = FOREACH gr_pl GENERATE group, COUNT(multiply) ; DESCRIBE dist_pl; STORE fermees INTO $CONTAINER/$PSEUDO/velibpy_results/fermees.txt USING PigStorage( \t ) ; STORE dist_av INTO $CONTAINER/$PSEUDO/velibpy_results/distribution_bikes.txt USING PigStorag STORE dist_pl INTO $CONTAINER/$PSEUDO/velibpy_results/distribution_stands.txt USING PigStora In [169]: %hd_pig_submit json_velib_python3.pig -stop_on_failure Out[169]: { id : job 1416874839254 0127 } In [173]: st = %hd_job_status job_1416874839254_0127 st["id"],st["percentcomplete"],st["status"]["jobcomplete"] Out[173]: ( job 1416874839254 0127, 100% complete, True) In [177]: %tail_stderr job_1416874839254_0127 10 Out[177]: <IPython.core.display.HTML at 0xc285b50> In [178]: %blob_ls /$PSEUDO/velibpy_results Out[178]: name \ 0 xavierdupre/velibpy results 1 xavierdupre/velibpy results/distribution bikes... 2 xavierdupre/velibpy results/distribution bikes... 3 xavierdupre/velibpy results/distribution bikes... 4 xavierdupre/velibpy results/distribution stand... 5 xavierdupre/velibpy results/distribution stand... 6 xavierdupre/velibpy results/distribution stand... 7 xavierdupre/velibpy results/fermees.txt 8 xavierdupre/velibpy results/fermees.txt/ SUCCESS 9 xavierdupre/velibpy results/fermees.txt/part-r... 10 xavierdupre/velibpy results/firstjob 11 xavierdupre/velibpy results/firstjob/ SUCCESS 12 xavierdupre/velibpy results/firstjob/part-m-00000 13 xavierdupre/velibpy results/multiply.txt 14 xavierdupre/velibpy results/multiply.txt/ SUCCESS 15 xavierdupre/velibpy results/multiply.txt/part-... last modified content type content length \ 0 Thu, 27 Nov 2014 08:56:03 GMT application/octet-stream 0 1 Fri, 28 Nov 2014 01:50:54 GMT 0 2 Fri, 28 Nov 2014 01:50:54 GMT application/octet-stream 0 3 Fri, 28 Nov 2014 01:50:54 GMT application/octet-stream 497 4 Fri, 28 Nov 2014 01:50:55 GMT 0 5 Fri, 28 Nov 2014 01:50:55 GMT application/octet-stream 0 6 Fri, 28 Nov 2014 01:50:55 GMT application/octet-stream 477 7 Fri, 28 Nov 2014 01:50:54 GMT 0 8 Fri, 28 Nov 2014 01:50:54 GMT application/octet-stream 0 9 Fri, 28 Nov 2014 01:50:53 GMT application/octet-stream 37 10 Thu, 27 Nov 2014 22:39:39 GMT 0 11 Thu, 27 Nov 2014 22:39:39 GMT application/octet-stream 0 12 Thu, 27 Nov 2014 22:39:39 GMT application/octet-stream 4693699 7

13 Fri, 28 Nov 2014 01:46:41 GMT 0 14 Fri, 28 Nov 2014 01:46:41 GMT application/octet-stream 0 15 Fri, 28 Nov 2014 01:46:41 GMT application/octet-stream 4693699 blob type 0 BlockBlob 1 BlockBlob 2 BlockBlob 3 BlockBlob 4 BlockBlob 5 BlockBlob 6 BlockBlob 7 BlockBlob 8 BlockBlob 9 BlockBlob 10 BlockBlob 11 BlockBlob 12 BlockBlob 13 BlockBlob 14 BlockBlob 15 BlockBlob In [179]: if os.path.exists("distribution_bikes.txt") : os.remove("distribution_bikes.txt") %blob_downmerge /$PSEUDO/velibpy_results/distribution_bikes.txt distribution_bikes.txt Out[179]: distribution bikes.txt In [180]: import pandas df = pandas.read_csv("distribution_bikes.txt", sep="\t", names=["nb_velos", "nb_stations_minut df.head() Out[180]: nb velos nb stations minutes 0 0 8586 1 1 6698 2 2 4904 3 3 3863 4 4 2887 In [182]: import matplotlib.pyplot as plt plt.style.use( ggplot ) df.plot(x="nb_velos",y="nb_stations_minutes",kind="bar",figsize=(16,4)) Out[182]: <matplotlib.axes. subplots.axessubplot at 0xae39f90> 8

In [183]: if os.path.exists("distribution_stands.txt") : os.remove("distribution_stands.txt") %blob_downmerge /$PSEUDO/velibpy_results/distribution_stands.txt distribution_stands.txt Out[183]: distribution stands.txt In [184]: df = pandas.read_csv("distribution_stands.txt", sep="\t", names=["nb_places", "nb_stations_min df.plot(x="nb_places",y="nb_stations_minutes",kind="bar",figsize=(16,4)) Out[184]: <matplotlib.axes. subplots.axessubplot at 0xab50d50> In [185]: if os.path.exists("fermees.txt") : os.remove("fermees.txt") %blob_downmerge /$PSEUDO/velibpy_results/fermees.txt fermees.txt Out[185]: fermees.txt In [186]: df = pandas.read_csv("fermees.txt", sep="\t", names=["status", "nb_velos_stations_minutes", "n df=df.set_index("status") df = df.t df["%close"] = df.closed / (df.closed + df.open) df Out[186]: status OPEN CLOSED %close nb velos stations minutes 1066055 3111 0.002910 nb places stations minutes 1276138 122 0.000096 Ce dernier tableau n est vrai que dans la mesure où les nombres reportées sont fiables lorsque les stations sont fermées. 1.5 Exercice 3 : stations fermées, journée complète Appliquer cela à une journée complète revient à lancer le même job sur des données plus grandes. On verra bientôt commencer éviter de recopier le job une seconde fois (introduisant une source potentielle d erreur). In [40]: 9

1.6 Exercice 4 : astuces Les erreurs de PIG ne sont pas très explicite surtout si elles se produisent dans le script python. Un moyen simple de débugger est d attraper les exceptions produites par python et de les récupérer sous PIG (le reste du job est enlevé). On peut tout-à-fait imaginer ajouter la version de python installée sur le cluster ainsi que la liste de modules In [70]: %%PYTHON jython.py import sys @outputschema("brow:chararray") def information(row): return (";".join([str(sys.version), str(sys.executable)])).replace("\n"," ") On vérifie que le script fonctionne avec jython : In [71]: %%jython jython.py information n importe quoi Out[71]: <IPython.core.display.HTML at 0xb066630> In [78]: %%PIG info.pig REGISTER $CONTAINER/$SCRIPTPIG/jython.py using jython as myfuncs; jspy = LOAD $CONTAINER/velib_1h1/*.txt USING PigStorage( \t ) AS (arow:chararray); one = LIMIT jspy 1 ; infos = FOREACH one GENERATE myfuncs.information(arow); STORE infos INTO $CONTAINER/$PSEUDO/results/infos USING PigStorage( \t ) ; In [79]: if client.exists(bs, client.account_name, "$PSEUDO/results/infos"): r = client.delete_folder (bs, client.account_name, "$PSEUDO/results/infos") print(r) In [80]: %hd_pig_submit info.pig jython.py -stop_on_failure Out[80]: { id : job 1416874839254 0107 } In [83]: st = %hd_job_status job_1416874839254_0107 st["id"],st["percentcomplete"],st["status"]["jobcomplete"] Out[83]: ( job 1416874839254 0107, 100% complete, True) In [84]: %tail_stderr job_1416874839254_0107 10 Out[84]: <IPython.core.display.HTML at 0xaa9f770> In [85]: if os.path.exists("infos.txt") : os.remove("infos.txt") %blob_downmerge /$PSEUDO/results/infos infos.txt Out[85]: infos.txt In [86]: %head infos.txt Out[86]: <IPython.core.display.HTML at 0xc1ab5f0> In [ ]: 10