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

Python Discussion :

Réécriture formatée de colonnes de données sans virgule dans un fichier de sortie


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    responsable R1D
    Inscrit en
    Février 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : responsable R1D
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2020
    Messages : 8
    Par défaut Réécriture formatée de colonnes de données sans virgule dans un fichier de sortie
    Bonjour,

    je suis complètement néophyte en Python mais je dois modifier quelques milliers de fichiers ascii contenant des données sur 2 colonnes et je galère dans la l'écriture formatée (en 20f8)de ces données.
    Je n'arrive pas à supprimer l'écriture de la virgule. J'utilise la commande "reader = csv.DictReader(in_file)" pour lire les fichiers initiaux.
    Il y a certaine une manière simple de faire ça !
    Merci par avance de votre aide.
    Arnaud

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Tu ne voudrais pas nous donner un petit jeu d'essai, histoire de voir ce que tu as en entrée? Et nous dire comment tu le veux en sortie? Parce que là ton explication est plus que nébuleuse.
    Accessoirement montrer tes codes et dire ce que tu as fait serait un plus. Parce que ton reader = csv.DictReader(in_file) c'est que dalle. Ok tu lis les fichiers mais comme visiblement ce n'est pas à la lecture que ça chie...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre du Club
    Homme Profil pro
    responsable R1D
    Inscrit en
    Février 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : responsable R1D
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2020
    Messages : 8
    Par défaut
    Les fichiers sont nommés de la manière suivante :
    AMP_EXXXXX.txt
    Voici un exemple des données initiales.
    0.0000100,0.0
    0.0000200,0.0
    0.0000300,0.0
    0.0000400,0.0

    Voici ce que je veux en sortie:
    Au début du fichier, l'entête suivante :
    *DEFINE_CURVE
    $# lcid sidr sfa sfo offa offo dattyp lcint
    AMP_EXXX - 0 1000.0 1.0 0.0 0.0 0 0
    $# A1 O1

    AMP_EXXXXX - doit être replacé par XXXXX où les XXXXX représente un nombre dans la réalité

    Sous cette entête, il faut écrire les données formatées comme ceux-ci :
    0.00002000 0.00000000
    0.00003000 0.00000000
    0.00004000 0.00000000
    0.00005000 0.00000000
    0.00006000 0.00000000
    0.00007000 0.00000000
    0.00008000 0.00000000
    0.00009000 0.00000000

    Voici ma tentative de script :
    import csv

    # Ouverture du fichier d'entrée en mode lecture
    with open('AMP_EXXX.txt', 'r') as in_file:
    # Utilisation de DictReader pour lire les données CSV
    reader = csv.DictReader(in_file)
    # Ouverture du fichier de sortie en mode écriture
    with open('output.csv', 'w') as out_file:
    # Utilisation de writer pour écrire les données dans un fichier CSV
    writer = csv.writer(out_file)
    # Boucle sur chaque ligne de données dans le fichier d'entrée
    for row in reader:
    # Récupère les valeurs de chaque colonne
    values = [float(row[col]) for col in reader.fieldnames]
    # Format les valeurs pour avoir 2 chiffres après la virgule
    values = [format(val, '20.8f').replace(',',' ') for val in values]
    # Ecriture de les valeurs dans le fichier
    writer.writerow(values)

    Merci par avance.

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par additive Voir le message
    Voici un exemple des données initiales.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    0.0000100,0.0
    0.0000200,0.0
    0.0000300,0.0
    0.0000400,0.0
    Voici ma tentative de script :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ...
    values = [float(row[col]) for col in reader.fieldnames]
    Ok. Il est clair que tu ne peux pas utiliser float() parce que 0.0000100,0.0 ce n'est pas un float !!! Ben oui, depuis quand les float ont 2 virgules anglo-saxonnes et une virgule française??? Je ne pige même pas comment ce code peut marcher car moi je tape float("0.0000100,0.0") et j'ai un ValueError direct...
    La virgule française pourrait être le séparateur milliers sauf que mettre un séparateur milliers dans la partie décimale du nombre ça ne s'est jamais vu. Et reste cette histoire des deux "points"...

    Citation Envoyé par additive Voir le message
    Sous cette entête, il faut écrire les données formatées comme ceux-ci :
    0.00002000 0.00000000
    Ok. Donc 0.0000200,0.0 doit donner 0.00002000. La virgule française disparait donc, ainsi que ce qui suit le second ".".
    De là on peut pondre ce petit code...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import re
    data=(
    	"0.0000100,0.0",
    	"0.0000200,0.0",
    	"0.0000300,0.0",
    	"0.0000400,0.0",
    )
     
    for d in data:
    	print(re.sub(r"(^.{1,})\..{1,}", r"\1", d).replace(",", ""))

    Et au résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    0.00001000
    0.00002000
    0.00003000
    0.00004000
    Ne reste que les fioritures (les "0.00000000").
    Et print() peut s'appliquer aux fichiers (print(..., file=out_file)).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre du Club
    Homme Profil pro
    responsable R1D
    Inscrit en
    Février 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : responsable R1D
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2020
    Messages : 8
    Par défaut
    Merci pour ton aide.
    Mais pour afficher la seconde colonne à la suite de la première car dans ton résultat on ne voit que la première ?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    J'ai compris. la virgule c'est le séparateur de champs. Ce n'est pas un nombre "0.0000200,0.0" mais deux nombres "0.0000200" et "0.0" !!!
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import csv
    from io import StringIO
    data=(
    	"0.0000100,0.0",
    	"0.0000200,0.0",
    	"0.0000300,0.0",
    	"0.0000400,0.0",
    )
     
    for d in data:
    	for x in csv.reader(StringIO(d), delimiter=","):
    		print("{0:>02.8f} {1:>02.8f}".format(*map(float, x)))
    Résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    0.00001000 0.00000000
    0.00002000 0.00000000
    0.00003000 0.00000000
    0.00004000 0.00000000
    Le module StringIO sert à transformer une string en flux IO (en fichier) ce qui me permet de le renvoyer à csv.reader. De ton côté comme tu lis un fichier tu n'en as pas besoin, tu prends directement le fichier en csv.reader...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    ou peut-être aussi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    data = (    
        "0.0000100,0.0",
        "0.0000200,0.0",
        "0.0000300,0.0",
        "0.0000400,0.0",
    )
     
    for d in data:
        x = [float(i) for i in d.split(",")]
        print("{0:>02.8f} {1:>02.8f}".format(*x))

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    C'est plus simple à écrire (et on peut encore aller plus simplement avec x = map(float, d.split(",")) et finalement virer le "x") mais n'oublions pas que les datas d'origines sont prises dans un fichier. Moi j'ai tapé ce jeu d'essai vite fait mais j'utilise StringIO justement pour faire "comme si" les datas étaient lues depuis un fichier parce que ce sera le cas dans le code final.
    Et pour un fichier, csv.reader c'est bien => https://sebsauvage.net/wiki/doku.php?id=csv
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Question de goût, mais disons que je trouve plus lisible les liste comprehension et adapté au petit jeu de données, et map pour un jeu de données bien plus important, cependant plus complexe à lire.

    On peut lire un fichier de plusieurs manières, commencer par quelque chose de simple avec with open connu par les débutant et par la suite viser les performances avec mmap si besoin.

  10. #10
    Membre du Club
    Homme Profil pro
    responsable R1D
    Inscrit en
    Février 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : responsable R1D
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2020
    Messages : 8
    Par défaut
    Merci pour votre aide.
    Je reviendrai vers voi si nouveau problème.
    Bon WE.

  11. #11
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Citation Envoyé par additive Voir le message
    Merci pour votre aide.
    Je reviendrai vers voi si nouveau problème.
    Bon WE.
    Une proposition efficace en attendant une réponse simple du PO avec mmap, très peu souvent utilisé,

    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
    import mmap
    import os
     
    DIRECTORY = "files"
     
     
    def format_number(number):
        return f"{float(number):.8f}"
     
     
    for filename in os.listdir(DIRECTORY):
        if not filename.endswith(".txt"):
            continue
        path = os.path.join(DIRECTORY, filename)
        outfile = f"{path}_out"
        with open(path, 'r') as f_in, open(outfile, 'w') as f_out:
            mmapped_file = mmap.mmap(f_in.fileno(), 0, access=mmap.ACCESS_READ)
            lines = []
            line = mmapped_file.readline()
            while line:
                col_1, col_2 = line.decode().strip().split(',')
                lines.append(f"{format_number(col_1)} {format_number(col_2)}\n")
                line = mmapped_file.readline()
     
            f_out.write("".join(lines))

  12. #12
    Membre du Club
    Homme Profil pro
    responsable R1D
    Inscrit en
    Février 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : responsable R1D
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2020
    Messages : 8
    Par défaut
    Bonsoir,

    Désolé mais je n'y arrive pas §
    J'ai l'rereur suivante en partant de données lues dans un fichier :
    (base) D:\CIMES\Mont_Blanc_Composite\Test_transfert\Python-CHATGPT\Test2>script_curve.py
    File "D:\CIMES\Mont_Blanc_Composite\Test_transfert\Python-CHATGPT\Test2\script_curve.py", line 26
    x = map(float, d.split(","))
    ^
    IndentationError: expected an indented block

    Mon code :
    import os

    # Définissez le répertoire contenant les fichiers textes
    directory = 'D:\CIMES\Mont_Blanc_Composite\Test_transfert\Python-CHATGPT\Test2'

    # Parcourez tous les fichiers textes dans le répertoire
    for filename in os.listdir(directory):
    if filename.endswith('.txt'):
    # Ouvrez le fichier
    with open(os.path.join(directory, filename), 'r') as f:
    # Comptez le nombre de lignes
    lines = f.readlines()
    line_count = len(lines)
    truncated_string = filename[4:-4]
    # Écrivez le nombre de lignes en première ligne du fichier
    with open(os.path.join(directory, filename), 'w') as f:
    #f.write(str(line_count) + '\n')
    f.write("*DEFINE_CURVE\n")
    f.write("$# lcid sidr sfa sfo offa offo dattyp lcint\n")
    f.write('{:>.10}'.format(truncated_string) + " 0 1000.0 1.0 0.0 0.0 0 0\n")
    f.write("$# A1 O1\n")
    f.writelines(lines)
    for d in lines:
    x = map(float, d.split(","))
    print("{0:>02.8f} {1:>02.8f}".format(*x))

  13. #13
    Membre du Club
    Homme Profil pro
    responsable R1D
    Inscrit en
    Février 2020
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : responsable R1D
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2020
    Messages : 8
    Par défaut
    voici ce que contient d :
    0.0084200,4.99999999999e-06

    0.0084300,1.5e-05

    0.0084400,1.5e-05

    0.0084500,2e-05

    0.0084600,2.5e-05

    0.0084700,3.5e-05

    0.0084800,4.5e-05

    0.0084900,6e-05

    0.0085000,8e-05

    0.0085100,0.0001

    0.0085200,0.00013

    0.0085300,0.000165

    0.0085400,0.00021

    0.0085500,0.00027

    je pense qu'il faut transformer cette chaîne de caractères en numérique, non ?

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par additive Voir le message
    Désolé mais je n'y arrive pas
    J'ai l'rereur suivante en partant de données lues dans un fichier :
    x = map(float, d.split(","))
    ^
    IndentationError: expected an indented block
    Non mais c'est bon quoi. Tu vas nous poster toutes tes erreurs de syntaxe en disant à chaque fois "'désolé mais je n'y arrive pas" ? Ben désolé mais sors-toi un peu les doigts parce que désolé mais tu es supposé connaitre les bases du langage. Pour exécuter une instruction dans la boucle il faut indenter ladite instruction. Et au cas où tu ne l'aurais pas remarqué, un code ici ça se place entre balises. Ca a été montré dans nos exemples, c'est écrit dans les règles et dans ma signature !!!

    Citation Envoyé par additive Voir le message
    je pense qu'il faut transformer cette chaîne de caractères en numérique, non ?
    Perspicace !!! Ben c'est justement le rôle de l'instruction x = map(float, d.split(","))
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Le message indique une erreur d'indentation, pour vous aider, pas le choix que de respecter les règles en mettant le code entre balises adaptées...

    Ensuite, faîtes cela sur un interpréteur python,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> d = "0.0085300,0.000165"
    >>> x = map(float, d.split(","))
    >>> list(x)
    [0.00853, 0.000165]
    >>> print("{0:>02.8f} {1:>02.8f}".format(*x))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: Replacement index 0 out of range for positional args tuple
    mais en faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> x = list(map(float, d.split(",")))
    >>> print("{0:>02.8f} {1:>02.8f}".format(*x))
    0.00853000 0.00016500
    on règle le problème, mais sans notion, difficile de comprendre les erreurs, il faut commencer par le commencement...

Discussions similaires

  1. Réponses: 12
    Dernier message: 26/08/2015, 20h10
  2. [XL-2013] colonne de données sans doublons
    Par ElGringo56 dans le forum Excel
    Réponses: 1
    Dernier message: 20/09/2014, 13h42
  3. données sans statistiques dans un histogramme
    Par Can10ce dans le forum SAS STAT
    Réponses: 3
    Dernier message: 23/12/2010, 11h40
  4. [Dojo] Grid : Charger des données sans passer par un fichier
    Par Johor dans le forum Bibliothèques & Frameworks
    Réponses: 3
    Dernier message: 28/12/2009, 19h34
  5. Développer une base de données sans BDE dans DELPHI 3 PRO
    Par ndlh721 dans le forum Bases de données
    Réponses: 3
    Dernier message: 05/02/2005, 14h21

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