Bonjour,

Après quelques mois pour apprendre le python, j'ai réussi à faire un code Python pour extraire des données d'un fichier XML (fichier Suunto, montre de sport avec GPS et fréquence cardiaque).
Les données sont lues, traitées dans un dataframe, extrapolées, ....

Le programme fonctionne mais j'essaye de l'optimiser sans trop de succès. Pouvez-vous svp jeter un coup d’œil sur mon code et me remonter les possibilités d’optimisation ? Je cherche à gagner du temps de calcul car ce soft, dans une future version, traitera plusieurs centaines de fichiers XML automatiquement.

En passant de minidom à lxml, j'ai déjà gagné pas mal de temps.

Merci d'avance.

Ci-dessous le code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# -*- coding: utf-8 -*-
"""
Created on Sat Nov  5 23:01:26 2016
 
@author: Remy
"""
 
import pandas
import matplotlib.pyplot as plt
import numpy as numpy
import logging
 
from lxml import etree
 
lignes = []
 
def parseXML(nomfichier, ns):
    "Parser LXLM"
 
    tree = etree.parse(nomfichier)
    root = tree.getroot()
 
    for elem in root.iter(ns+'Sample'):
        try:
            UTCtime = elem.findtext(ns+'UTC')
        except ValueError:
            logging.info('%s, Erreur UTCtime', nomfichier)
            UTCtime = numpy.nan
 
        try:            
            time = elem.findtext(ns+'Time')
        except ValueError:
            logging.info('%s, Erreur Time', nomfichier)
            time = numpy.nan
 
        try:
            latitude = elem.findtext(ns+'Latitude')
        except ValueError:
            logging.info('%s, Erreur Latitude', nomfichier)
            latitude = numpy.nan
 
        try:
            longitude = elem.findtext(ns+'Longitude')
        except ValueError:
            logging.info('%s, Erreur Longitude', nomfichier)
            longitude = numpy.nan
 
        try:
            distance = elem.findtext(ns+'Distance')
        except ValueError:
            logging.info('%s, Erreur Distance', nomfichier)
            distance = numpy.nan
 
        try:
            speed = elem.findtext(ns+'Speed')
        except ValueError:
            logging.info('%s, Erreur Speed', nomfichier)
            speed = numpy.nan
 
        try:
            cadence = elem.findtext(ns+'Cadence')
        except ValueError:
            logging.info('%s, Erreur Cadence', nomfichier)
            cadence = numpy.nan
 
        try:
            altitude = elem.findtext(ns+'Altitude')
        except ValueError:
            logging.info('%s, Erreur Altitude', nomfichier)
            altitude = numpy.nan
 
        try:
            gpsaltitude = elem.findtext(ns+'GPSAltitude')
        except ValueError:
            logging.info('%s, Erreur GPSAltitude', nomfichier)
            gpsaltitude = numpy.nan
 
        try:
            heartrate = elem.findtext(ns+'HR')
        except ValueError:
            logging.info('%s, Erreur HR', nomfichier)
            heartrate = numpy.nan
 
        try:
            energy = elem.findtext(ns+'EnergyConsumption')
        except ValueError:
            logging.info('%s, Erreur EnergyConsumption', nomfichier)
            energy = numpy.nan
 
        try:
            temperature = elem.findtext(ns+'Temperature')
        except ValueError:
            logging.info('%s, Erreur Temperature', nomfichier)
            temperature = numpy.nan
 
        ligne = (UTCtime, time, latitude, longitude, distance, speed, cadence, altitude, gpsaltitude, heartrate, energy, temperature)                
        lignes.append(ligne)
 
def main():
    "Programme principal"
    global df
 
    #Initialation du fichier Log
    logging.basicConfig(filename = 'test_parsing.log', filemode = 'w', level=logging.DEBUG)
 
    #Parser LXML
    namespace = '{http://www.suunto.com/schemas/sml}'
    nomfichier = 'D9F698461C000D00-2016-09-24T09_59_45-0.sml'
    parseXML(nomfichier, namespace)
 
    #Création d'un Dataframe Pandas avec le fichier parsé par lxml pour les données des Samples
    #Interpolation linéaire des données manquantes avec interpolate()
    #Les premières données manquantes sont recopiées en prenant les premières valides avec fillna()    
    #Les dernières données manquantes sont recopiées en prenant les dernières valides avec fillna() 
    colonnes = ['UTCtime', 'time', 'latitude', 'longitude', 'distance', 'speed', 'cadence', 'altitude', 'gpsaltitude', 'heartrate', 'energy', 'temperature']
    df = pandas.DataFrame(data = lignes, columns = colonnes)
    df.fillna(value=numpy.nan, inplace=True)
    df = df.interpolate(axis = 0).fillna(method = 'bfill').fillna(method = 'ffill')
 
    #On passe en "entier" les données qui peuvent être simplifiées
    #Les données en "float" sont arrondis à 2 décimales (hors latitude & longitude)   
    df['time'] = df['time'].astype(float).round(2)
    df['latitude'] = df['latitude'].astype(float)
    df['longitude'] = df['longitude'].astype(float)
    df['distance'] = df['distance'].astype(int)
    df["speed"] = df["speed"].astype(float).round(2)
    df["cadence"] = df["cadence"].astype(float).round(2)
    df['altitude'] = df['altitude'].astype(int).round(2)
    df['gpsaltitude'] = df['gpsaltitude'].astype(float).round(2)
    df['heartrate'] = df['heartrate'].astype(float).round(2)
    df['energy'] = df['energy'].astype(float).round(2)
    df['temperature'] = df['temperature'].astype(float).round(2)
 
    #Calcul de la moyenne des altitudes baro et GPS
    #L'altitude baro (plus stable) est recalée sur la moyenne GPS par offset
    altitudebaro = numpy.mean(df['altitude'])
    altitudegps = numpy.mean(df['gpsaltitude'])
    df['altitude'] = df['altitude'] + int(altitudegps - altitudebaro)
 
    #Graphs divers
    fig = plt.figure()
    plt.title('Tracé 2D')
    plt.plot(df['longitude'], df['latitude']) #, marker='o', markersize=1)
 
    fig = plt.figure()
    plt.title('Altitude Baro - GPS')
    plt.plot(df['altitude'])
    plt.plot(df['gpsaltitude'])
 
    fig = plt.figure()
    plt.title('Vitesse')
    plt.plot(df["speed"])
 
    fig = plt.figure()
    plt.title('Cadence')
    plt.plot(df['cadence'])
 
    fig = plt.figure()
    plt.title('Fréquence cardiaque')
    plt.plot(df['heartrate'])
 
if __name__ == "__main__":
    main()