Créer un site internet

Importer et traiter des données avec Python

C07_Import_et_traces

Pour commencer, exécuter la cellule ci-dessous (import des fonctions de base) et les cellules de la partie Fonctions support en fin de fichier : fonction de lissage et fonction d'import de données

In [ ]:
%pylab inline
# réalise les imports suivants :
# import numpy as np
# import matplotlib.pyplot as plt

Import des données expérimentales

Les cellules ci-dessous donnent des exemples pour importer les données provenant du bras robot, de la cheville Nao, du robot Ericc et d'un résultat numérique dans Méca3D (export d'une courbe). Une courbe utilisant la fonction de lissage est aussi tracée.

Pour que l'import soit simple, il faut que le fichier de données soit dans le même répertoire que ce fichier notebook.

Robot Nao

In [ ]:
nom_fichier = 'bras.txt'
t, angle_coude, angle_epaule, courant_coude, courant_epaule = lectureCSV(nom_fichier, 1) # import des données

plt.plot(t, courant_coude) # courbe de courant
plt.plot(t, lissage(courant_coude, 20), linewidth=2) # courbe lissée

Cheville Nao

On suppose que le fichier contient, dans l'ordre et en colonnes, les données suivantes :

  • consigne de tangage, angle de tangage, angle de roulis,
  • courant moteur tangage, courant moteur roulis.

A chaque donnée est associée une colonne de temps. une première colonne comprend un numéro de point.

Ouvrir le fichier résultat pour plus de précision

In [ ]:
nom_fichier = 'cheville.txt'

# Import des  colonnes d'indice 7 et 8 (les 8ème et 9ème) uniquement.
# on suppose qu'il s'agit du temps et du courant de tangage
t, courant_tangage = lectureCSV(nom_fichier, nbsaut=3, decimal=',', cols=(7, 8))

plt.plot(t, courant_tangage) # courbe de courant de tangage
plt.plot(t, lissage(courant_tangage, 20), linewidth=2) # courbe lissée

Robot Ericc

On suppose que le fichier provient d'une expérimentation comprenant 500 points pour une mesure de 20 s.

Cependant, le fichier résultat ne comprend pas exactement 500 points.

On suppose dans l'exemple que l'angle de lacet est en 1ère colonne (indice 0) et que le courant moteur est en 4ème colonne (indice 3)

In [ ]:
nom_fichier = "ericc.txt"
angle_coude, courant_coude = lectureCSV(nom_fichier, nbsaut=4, decimal=',', cols=(0,3))

# création des temps (non contenus dans le fichier résultat et non indispensable pour le TP)
dt = 20 / (len(courant_coude)) # expérience de 20s
t = np.linspace(0, dt * (len(courant_coude)-1), len(courant_coude))

plt.plot(t, courant_coude) # courbe de courant
plt.plot(t, lissage(courant_coude, 5)) # courbe lissée

Fonctions support

Il faut exécuter les cellules ci-dessous.

Définition d'une fonction assurant le lissage d'une courbe par moyenne centrée

In [ ]:
def lissage(x,l):
    """retourne un tableau correspondant aux valeurs de x
    lissees par moyenne flottante centree de largeur l."""
    res = x.copy()  # duplication des donnees
    for i in range (1,len(x)-1): # tous les points sauf le premier et le dernier
        l_g = min(i,l)          # nombre de points disponibles a gauche
        l_d = min(len(x)-i-1,l) # nombre de points disponibles a droite
        li=min(l_g,l_d)
        res[i]=np.sum(x[i-li:i+li+1])/(2*li+1)
    return(res)

Lecture d'un fichier texte ayant des données numériques en colonne (type fichier csv)

In [ ]:
def lectureCSV(nomfic,nbsaut=0,nbfin=0,decimal='.',cols=[],sep='; \t',encoding="cp1252"):
    """Retourne sous forme d'une liste de tableaux numpy les données présentes 
    en colonne dans un fichier texte
    nomfic : nom du fichier
    nbsaut : nombre de lignes à sauter en début de fichier (0 par défaut)
    nbfin : nombre de lignes non vides à ne pas prendre en compte en fin de fichier (0 par défaut)
    decimal : caractère du séparateur décimal (. par défaut)
    cols : indice des colonnes à récupérer (toutes et dans l'ordre par défaut).
    sep : caractères séparant les colonnes (; espace ou tabulation par défaut)
    encoding : codage des caractères (cp1252 de windows par defaut)
    Exemple d'utilisation : a,b,c = lectureCSV("resultats.csv",4,0,',',[0,1,3],';')
                            pour récupérer les données des première, deuxième et quatrième colonnes
                            à partir de la 5ème ligne
                            séparées uniquement par ;
                            avec le caractère , comme séparateur décimal"""
    def mysplit(txt,sep):
        mots = []
        mot = ""
        un_mot = False
        i = 0
        # recherche premier caractère
        while i < len(txt) and (txt[i] in sep): i = i + 1
        if i == len(txt): return mots
        # décomposition en mots
        for c in txt[i:]:
            if c not in sep:
                mot = mot + c
                un_mot = True
            else:
                if un_mot:
                    mots.append(mot)
                    mot = ""
                    un_mot = False
        if un_mot: mots.append(mot)
        return mots
            
    print("Import du fichier :", nomfic)
    try:
        fic = open(nomfic,'r',encoding=encoding)
    except:
        print("Erreur d'ouverture du fichier. Est-il dans le répertoire de travail ?")
        return
    
    # lecture de toutes les lignes
    lignes = fic.readlines()
    fic.close()

    # recherche indice derniere ligne à prendre en compte
    ifin = len(lignes)
    i = nbfin
    while i > 0 and ifin > nbsaut:
        if len(lignes[ifin-1].strip()) > 0: i = i - 1
        ifin = ifin - 1
    if ifin == nbsaut:
        print("Erreur de cohérence entre nbsaut, nbfin, et le nombre de lignes du fichier.")
        return

    # création de la liste de listes des résultats
    res=[]
    if len(cols) == 0:
        cols = list(range(len(mysplit(lignes[nbsaut],sep))))
    for i in range(len(cols)): res.append([])

    # création des listes de résultats
    for ligne in lignes[nbsaut:ifin]:  
        if len(ligne.strip()) > 0 :
            vals = mysplit(ligne.strip().replace(decimal,'.'),sep)
            for i,col in enumerate(cols):
                res[i].append(float(vals[col]))
    # conversion du résultat en liste de tableaux
    for i,x in enumerate(res):
        res[i]=np.array(x)
    if len(res)==1: return res[0]
    return res

Date de dernière mise à jour : 01/12/2020

  • Aucune note. Soyez le premier à attribuer une note !

Ajouter un commentaire

 
×