• # sauver un châton

    Posté par . En réponse au journal [HS] Prix des carburants vs. prix du brut : déphasage(s) ?. Évalué à 7 (+5/-0).

    Journal très sympa.

    J'ai quand même buggé sur :

    prévoyez de la RAM, chez moi ça en a pris ~22 Go pour parser tout ça

    Ça veut dire une machine avec 32GB de RAM. Pas trop dans mes moyens en ce moment.

    Je connais bien la structure des fichiers de données car j'ai déjà joué avec par le passé. Ils peuvent être parsé en mode texte car les xml sont bien indentés.

    Pour chaque par points de vente (pdv), il y a toutes les modifications de prix effectuées dans l'année : type de carburant, date, prix.

    Les fichiers ne sont pas triés pas dates mais par pdv, il faudra donc rassembler les données par date avant de les dumper.

    J'utilise donc le script awk suivant :

    # prix nom="Gazole" id="1" maj="2017-09-03 09:13:43" valeur="1.151"/>
    # 1ドル 2ドル 3ドル 4ドル 5ドル 6ドル 7ドル 8ドル 9ドル
    $1 == "prix nom=" {
     type = $4
     prix = +$8 < 100 ? +$8 : +$8 /1E3
     date = substr($6,1,10)
     k = type "@" date
     if (! N[k]++) { # first record for this (type, date)
     MAX[k] = MIN[k] = prix
     } else {
     if (prix > MAX[k]) { MAX[k]=prix }
     else if (prix < MIN[k]) { MIN[k]=prix }
     }
     SUM[k] += prix
     SQ2[k] += prix*prix
    }
    END {
     for (k in N) {
     type = substr(k,1,1)
     date = substr(k,3)
     AVG = SUM[k] / N[k]
     VAR = (SQ2[k] - 2*SUM[k]*AVG) / N[k] + AVG*AVG
     print date, AVG, MIN[k], MAX[k], sqrt(VAR) >> "stats_dir/type_" type ".txt"
     }
    }

    Il y a une petite gymnastique avec les clés de tableaux associatifs car MAWK ne supporte pas les tableaux imbriqués contrairement à GAWK mais est au moins deux fois plus rapide.

    Je fais la glue avec le script bash suivant:

    #!/bin/bash -eu
    AWK=mawk
    export LC_NUMERIC=en_GB.UTF-8
    TIME='/usr/bin/time -f %M,%P,%e,%U,%S,%W,%c,%w,%x'
    for y in $(seq 2007 2026);
    do
     echo $y
     $AWK -F "<" '{print 2ドル}' <(unzip -p 1_dl/PrixCarburants_annuel_${y}.zip PrixCarburants_\*.xml) \
     | $TIME $AWK -F '"' -vOFS=";" -f parse_pdv.awk
    done

    Le premier AWK permet de récupérer le contenu de la balise ouvrante XML. Pour le second on découpe les attributs XML avec le caractère ".

    Le script prend 54.73s pour process les 4.257GB de données et consomme en pic 3.356Mo de RAM ; oui, moins de 4 mégaoctets de RAM. Le script AWK est bien le facteur limitant (pas le premier awk ni le unzip).

    Pour produire six fichiers - un par type de carburant - de 7000 (=19*365) lignes chacun, pour 280Ko en tout, qu'il faudra alors charger dans pandas. J'imagine que cela ne prendra que quelques dizaine de Mo de RAM.

    Il faudra encore réaliser l’agrégation par semaine car le script AWK ne le fait pas. Il n'est là que pour diminuer drastiquement la quantité de données à charger dans Python.