IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Calcul scientifique Python Discussion :

genfromtxt, encodage et séparateur de milliers


Sujet :

Calcul scientifique Python

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2006
    Messages : 197
    Points : 185
    Points
    185
    Par défaut genfromtxt, encodage et séparateur de milliers
    Bonjour à tous.
    Je suis confronté à un problème de lecture de fichier. Certaines données sont écrites avec un espace en séparateur de miliers. Je ne parviens pas à les transformer en valeurs numériques.

    Je dois lire des données numériques d'un fichier texte provenant d'une machine d'aquisition. Je ne connais pas l'encodage (bien évidemment...) mais je soupsonne iso8859_15 (en tout cas, il arrive à le lire sans problème dans ce cas là).

    J'importe les données qu'il contient en utilisant genfromtxt de numpy. Bien évidemment, pour corser un peu les choses, le séparateur de décimale est une virgule. Du coup, j'importe sous forme de chaine de caractère, puis je remplace les virgules par des points, puis ensuite, je converti en float.

    Cela fonctionne bien tant que j'ai moins de 999 données. Au dessus, j'ai un séparateur de milliers (un espace). Et là, impossible de m'en débarasser. j'ai tenté un replace(" ","") sans succès. J'ai tenté de convertir la chaine en utf8 puis de faire replace(u" ","") sans succès. Au moment de la conversion, l'espace se transforme en un A surmonté du symbole ° et suivi d'un espace.

    Mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
            fich = io.open(self.fichier, encoding=self.encodage)
            temp = np.genfromtxt(fich, skip_header=self.nbHead, delimiter=self.sepCol, dtype=str)
            fich.close()
            for i in range(np.shape(temp)[0]):
                for j in range(np.shape(temp)[1]):
                    tempo = temp[i][j]
                    tempo = tempo.decode(self.encodage, errors='replace')
                    tempo = tempo.replace((u' ').encode(self.encodage),'')
                    temp[i][j] = temp[i][j].replace(self.sepDec,'.')
                    if not temp[i][j] :
                        temp[i][j] = str(np.nan)
            temp=temp.astype(np.float)
    lorsque je sors les valeurs de tempo avant et après le decode, j'ai le résultat suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1*434
    <type 'numpy.string_'>
    1Â*434
    <type 'unicode'>
    sauf que dans ma console, le caractère * est en fait un espace... (c'est bizare d'ailleurs...)

    Quelqu'un aurait-il une solution à me proposer concernant la gestion de ces séparateurs de milliers, et de la conversion en utf8 ? Y a-t-il une différence entre le str de python et le numpy.string ?

    Merci d'avance

    PS : je précise que je code en python 2.7, et que mes scripts sont en utf8. Je suis sous linux (mais mes scripts sont destinés à etre aussi utilisés sous windows...). Je code en utilisant spyder.

  2. #2
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2010
    Messages
    140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 140
    Points : 182
    Points
    182
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    string = '1Â*434'.decode('utf8', 'ignore')
    #string = 1*434
    string.replace('*','.')
    #string = 1.434
    string = float(string)
    c'est moche, mais ca marche

    cordialement

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2006
    Messages : 197
    Points : 185
    Points
    185
    Par défaut
    merci pour la réponse, malheureusement ça ne fonctionne pas.
    le caractère * est apparu a cause du copier coller de ma console vers le navigateur internet.

    en réalité, ce que j'obtient c'est qqchose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1 434
    <type 'numpy.string_'>
    1Â 434
    <type 'unicode'>
    c'est une plaie ces histoires d'encodage

    je joint une version légère du fichier que je veux traiter, ce sera plus simple je pense
    Fichiers attachés Fichiers attachés

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2006
    Messages : 197
    Points : 185
    Points
    185
    Par défaut
    pour rajouter un peu d'éléments à mon problème :

    si j'ouvre le fichier en utf-8 de la façon suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            fich = io.open(self.fichier, encoding='utf-8')
            temp = np.genfromtxt(fich, skip_header=self.nbHead, delimiter=self.sepCol, dtype=str)
    j'ai le message d'erreur suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UnicodeDecodeError: 'utf8' codec can't decode byte 0xa0 in position 60: invalid start byte
    Ce n'est pas le cas si je choisi iso8859_15, et c'est d'ailleurs ce que devine mon éditeur de texte sur ce fichier.

    donc en prenant iso8859_15, genfromtxt arrive à lire mon fichier.
    j'obtient des données de type 'numpy.string_'
    etant donné qu'un replace(' ','') ne fait rien directement, je converti en unicode en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tempo = tempo.decode('iso8859_15', errors='replace')
    et du coup j'obtient ça: 1Â*434 et c'est de type 'unicode'.

    si à la place, j'utilise ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    tempo = tempo.decode('utf-8', errors='replace')
    j'obtient bien un type unicode qui contient 1 434. Sauf que la fonction replace ne m'enlève pas l'espace, ce qui me laisse penser que l'espace que je vois je correspond pas à l'espace mais à un autre caractère...

  5. #5
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2010
    Messages
    140
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2010
    Messages : 140
    Points : 182
    Points
    182
    Par défaut
    Bonjour,

    j'ai fait ca

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    f = open('capteurTEST.txt')
    d = f.read()
    f.close()
    s = d.split(';')
    print s[6]
    mon_int = s[6].decode('ascii','ignore')
    print int(mon_int)
    c'est encore moche , mais ca marche pour moi meme sous windows

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2006
    Messages : 197
    Points : 185
    Points
    185
    Par défaut
    merci utopman.

    mais c'est très bizare... si tu affiche d, il donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    "P0";;
    "Index [1]";"exx [1] - Hencky";
    0;-1,67989e-17;
    1434;-0,599728;
    alors que si on regarde directement dans le fichier, on voit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    "P0";;
    "Index [1]";"exx [1] - Hencky";
    0;-1,67989e-17;
    1 434;-0,599728;
    et en réalité, le copié collé direct dans mon navigateur donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    "P0";;
    "Index [1]";"exx [1] - Hencky";
    0;-1,67989e-17;
    1*434;-0,599728;
    il y a donc bien un problème sur ce caractère... (d'ailleurs, pour info, quand je fait le copier coller dans le petit éditeur du forum, je vois un espace, et quand je fais une prévisualisation, il m'affiche ensuite une étoile à la place... c'est vraiment trop louche).

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2006
    Messages : 197
    Points : 185
    Points
    185
    Par défaut
    Quelqu'un aurait-il une idée sur ce problème d'encodage ?
    parceque la solution que je vois pour l'instant, c'est de ne pas utiliser genfromtxt et de coder un truc similaire à la main.
    mais sans trop comprendre pourquoi ça fonctionne directement en utilisant read(), je ne suis pas à l'abris de me retrouver dans une situation délicate sur un autre problème d'encodage un jour...

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,
    C'est pas si complique de faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> file = open('capteurTEST.txt', 'rb')
    >>> buffer = file.read()
    >>> print (buffer)
    b'"P0";;\n"Index [1]";"exx [1] - Hencky";\n0;-1,67989e-17;\n1\xa0434;-0,599728;\n\n'
    Ce que vous vous attendez a être un "SP" est codé '\xa' i.e. "LF" en ASCII.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2006
    Messages : 197
    Points : 185
    Points
    185
    Par défaut
    Salut.
    Effectivement, ce n'est pas compliqué. Mais mis à part l'ouverture en mode binaire, c'est exactement les deux premières lignes de l'exemple que m'a donné utopman. Et chez moi l'affichage de la chaine qui a été read() ne me donne pas la même chose que toi.

    Quand on fait un open() puis un read(), quel est l'encodage de la chaine lue ? Etant donné qu'on n'a pas précisé d'encodage pour l'ouverture du fichier, est-ce que c'est l'encodage du script python (ou de la console dans laquelle est lancé python )? est-ce que c'est un encodage par défaut ?

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,
    Et chez moi l'affichage de la chaine qui a été read() ne me donne pas la même chose que toi.
    Ce n'est pas "anormal", j'utilise Python3.
    Sinon vous pouvez utiliser la commande dump.
    Le but étant de voir le code des bytes qui seront lus et non l'affichage de leur interprétation en entrée puis en sortie par des mécanismes posant questions sur la question.

    Cà ne montre que des caractères <127.
    Aucun encoding ne les changera.
    Cc'est probablement ce que vous devriez utilisez pour le .replace (modulo du pourquoi ce LF au lieu du SP attendu).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Août 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Août 2006
    Messages : 197
    Points : 185
    Points
    185
    Par défaut
    Merci beaucoup.
    Je ne connaissais pas la commande dump. Je vais essayer ça tout de suite.
    c'est vrai qu'il y a des conversions multiples... et j'aurais du préciser surement que j'utilisais python 2.7, cela doit changer pas mal de choses au niveau de la gestion des encodages je pense.

    Désolé, je vous ai tutoyé alors que vous me vouvoyez, ce n'était pas intentionnel.

    Je vais tester le dump et voir ce que j'obtiens

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par gregory2526 Voir le message
    et j'aurais du préciser surement que j'utilisais python 2.7, cela doit changer pas mal de choses au niveau de la gestion des encodages je pense.
    Vous l'aviez mentionné dans votre post initial.
    Cela n'interdit pas d'avoir aussi une version 3.
    Ce qui change est la différence faite entre les types /bytes/ et /str/ que ne fait pas Python2.
    Ceci dit, si le fichier est encode en X pour le décoder, il faudra toujours savoir qui est X.

    Désolé, je vous ai tutoyé alors que vous me vouvoyez, ce n'était pas intentionnel.
    J'utilise le "vous" pour écrire et le "tu" pour parler. C'est un réflexe.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Séparateur de millier
    Par fo comlan dans le forum Général Python
    Réponses: 6
    Dernier message: 20/06/2007, 14h17
  2. [SQL] séparateur de millier
    Par moneyinthebank dans le forum Langage SQL
    Réponses: 4
    Dernier message: 19/10/2006, 11h36
  3. Séparateurs des milliers
    Par blowlagoon dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 26/05/2006, 10h02
  4. Format des nombres entiers, séparateurs de milliers
    Par zazaraignée dans le forum Langage
    Réponses: 2
    Dernier message: 26/10/2005, 01h25
  5. [VB.NET] Séparateur de milliers
    Par anael dans le forum Windows Forms
    Réponses: 4
    Dernier message: 24/03/2005, 15h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo