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écupération de date au format str dans fichier CVS et conversion en objet date [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Août 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2015
    Messages : 3
    Par défaut Récupération de date au format str dans fichier CVS et conversion en objet date
    Bonjour,

    je cherche à récupérer des dates d'un fichier cvs pour les enregistrer dans un tableau d'objet date. Il me faut donc lire la bonne colonne de date de type str, les convertir en objet date puis les enregistrer dans mon tableau de date. A l'exécution, l'interpréteur m'ouvre une fenêtre _strptime et pointe sur le ligne 359 suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if not found:
            raise ValueError("time data %r does not match format %r" %
                             (data_string, format))
    Le fichier de données au format cvs est comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    01/09/2019	0.016341
    01/08/2019	0.016366
    01/07/2019	0.016099
    Le programme pour lecture et de traitement des dates est le suivant :

    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
    from datetime import date, datetime
     
    defaultDate = '1900-01-01'
    objetDate = datetime.strptime(defaultDate, '%Y-%m-%d')
     
    nbDate = 1200
    MatrixDate = [objetDate for i in range(nbDate)]
     
    inpPIE = open ("PIE_FRF-SEK.csv", "r")
     
    entete = 0
    retroDate = 0
    for ligPIE in inpPIE :
        f1ligPIE = ligPIE.strip("\n\r")
        f2ligPIE = f1ligPIE.strip("\t")
        f3ligPIE = f2ligPIE.split(";")
     
        if(retroDate > 0):
            MatrixDev[nbDate-retroDate] = datetime.strptime(f3ligPIE[0], '%Y-%m-%d')
        retroDate += 1
     
    inpPIE.close()
    Merci pour vos éclairages

    Stéph.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Programme difficilement récupérable (surtout en Python où les tabulations sont impératives pour la compréhension de l'algo)


    J'ai quand-même réussi à faire un truc en essayant de "deviner" les structures de contrôle. Premier défaut, la variable "MatrixDev" n'existe pas (MatrixDate ?). Autre truc, si retroDate vaut 0, alors le test retroDate > 0 sera faux et le bloc "if" n'est jamais exécuté (hé oui, surprise mathématique, 0 n'est pas, je répète "n'est pas" supérieur à 0 !!!). Et enfin si la chaine est "01/09/2019 0.016341" alors f3ligPIE[0] contient ce "01/09/2019 0.016341" ce qui ne correspond pas à une date au format Y-m-d

    Citation Envoyé par hamoys Voir le message
    Merci pour vos éclairages
    Oui enfin c'était pas compliqué de remarquer que si une ligne contient "01/09/2019 0.016341" alors il n'y a pas de point-virgule pour les split ; de matcher intellectuellement ce que représente "Y", "m" et "d" pour une date ; et que si le séparateur est "slash" alors ce n'est pas un "tiret" quoi !!!
    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
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    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 762
    Par défaut
    Citation Envoyé par hamoys Voir le message
    Merci pour vos éclairages
    Sauf à lancer votre programme dans un environnement particulier, le message d'erreur raconte bien plus que vous ne le rapportez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> import datetime as dt
    >>> dt.datetime.strptime('123', '%Y-%m-%d')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\py_env\py34-64\lib\_strptime.py", line 500, in _strptime_datetime
        tt, fraction = _strptime(data_string, format)
      File "C:\py_env\py34-64\lib\_strptime.py", line 337, in _strptime
        (data_string, format))
    ValueError: time data '123' does not match format '%Y-%m-%d'
    >>>
    La dernière ligne affiche la chaîne de caractères qu'il ne sait pas convertir.

    Et comme la construction de votre paramètre sort des lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        f1ligPIE = ligPIE.strip("\n\r")
        f2ligPIE = f1ligPIE.strip("\t")
        f3ligPIE = f2ligPIE.split(";")
    vous savez ce qu'il vous faut revoir.

    De plus, si vos dates sont de la forme 01/08/2019, le format à utiliser pour la conversion n'est pas '%Y-%m-%d'.

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

  4. #4
    Membre à l'essai
    Homme Profil pro
    Chargé d'affaire
    Inscrit en
    Août 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chargé d'affaire
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2015
    Messages : 3
    Par défaut
    Merci pour vos contributions; en voulant simplifier l'exemple j'ai insérer des erreurs ou confusions. J'en reviens donc au source original retravailler pour intégrer 2 de vos remarques et pour essayer de rendre l'ensemble plus lisible.

    Les objectifs :
    Dans le tableau MatrixDateTPX et même avant avec l'objet ymdDate je souhaite convertir une chaine de caractères au format
    dd-mm-yyyy en objet date dans le format yyyy-mm-dd. C'est là ou je bloque car toutes les configurations que j'essaie produisent des messages d'erreur sauf quand je force ymdDate='1900-1-1' par exemple. problème de typage ?
    Dans le tableau MaxtrixDataOCDE je récupère uniquement des années ce qui m'a donné la possibilité de passer par des entiers avant de convertir en objet date. Ici tout se passe bien.

    voici le code ou j'espère que j'aurais utilisé correctement le marquage sur les balises cette fois-ci, sinon le fichier source en pièce jointe:

    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
     
    from datetime import date, datetime
     
    defaultDate = date(1900,1,1)
     
    nbDate = 1200
    MatrixDateTPX = [defaultDate for i in range(nbDate)]
    MatrixDateOCDE = [defaultDate for i in range(nbDate)]
    tabyearOCDE = [defaultDate for i in range(nbDate)]
     
    # format du fichier cvs 'PIE_FRF-SEK.csv', ou les colonnes sont biens distinctes :
    # Mois	        Moyenne FRA/SEK=	Min FRA/SEK=	Max FRA/SEK=	Nb jours ouvrés
    # 01/09/2019	0.016341	          0.016213	       0.016484	       7
    # 01/08/2019	0.016366	          0.016292	       0.016525	       22
    # 01/07/2019	0.016099	          0.015999	       0.016258	       23
    # ...
    inpPIE = open ("PIE_FRF-SEK.csv", "r")
     
    # format du fichier cvs "BdD-OCDE-PPP-1960-2018.csv", ou les colonnes sont biens distinctes :
    # '4 lignes d'entête sans intérêt
    # Date	Australie	Autriche	Belgique
    # 1960	0.700946	0.96508	    0.861825
    # 1961	0.701324	1.006974	0.863464
    # 1962	0.68799	    1.02202	    0.857953
    # ...
    inpPPP = open ("BdD-OCDE-PPP-1960-2018.csv", "r")
     
    enteteTPX = 0
    retroDate = 0
    for ligPIE in inpPIE :
        # 1. suppression des caractères spéciaux
        # 2. suppression des caractères inutiles " "
        # 3. suppression des caractères de séparations ";" pas utile ici mais conservé
        f1ligPIE = ligPIE.strip("\n\r")
        f2ligPIE = f1ligPIE.strip("\t")
        f3ligPIE = f2ligPIE.split(";")
     
        # chargement du résultat dans la matrice de travail
        # à prévoir : savoir combien de mois de l'année n sont chargé => info utile pour mise ne // avec PPP
        if(enteteTPX > 0):
            ymdDate = datetime.date.strptime(str(f3ligPIE[0]), '%d-%m-%Y')
            #MatrixDateTPX[(nbDate-1)-retroDate] = datetime.strptime(ymdDate,'%Y-%m-%d')
            retroDate += 1
        enteteTPX += 1
     
    inpPIE.close()
     
    enteteOCDE = 0
    retroDate = 0
    for ligPPP in inpPPP :
        # 1. suppression des caractères spéciaux
        # 2. suppression des caractères inutiles " "
        # 3. suppression des caractères de séparations ";" pas utile ici mais conservé
        f1ligPPP = ligPPP.strip("\n\r")
        f2ligPPP = f1ligPPP.strip("\t")
        f3ligPPP = f2ligPPP.split(";")
     
        # chargement du résultat dans la matrice de travail en commençant par la fin du tableau
        # ici on récupère récupère des années, puis convertion en int avant convertion en date du premier de chaque mois
        if(enteteOCDE > 3):
            tabyearOCDE[retroDate] = int(f3ligPPP[0])
            retroDate += 1
        enteteOCDE += 1
    inpPIE.close()
     
    for i in range (0, retroDate):
        MatrixDateOCDE[(nbDate-1) - (retroDate-1) + i] = date(tabyearOCDE[i],1,1)
    Merci pour les réponses.

    Stéph.
    Fichiers attachés Fichiers attachés

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    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 762
    Par défaut
    Salut,

    Citation Envoyé par hamoys Voir le message
    J'en reviens donc au source original retravailler pour intégrer 2 de vos remarques et pour essayer de rendre l'ensemble plus lisible.
    Ca apporte quoi de poster un code qui présente les mêmes défauts que ceux déjà mentionnés?
    Si le format de votre fichier est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    # format du fichier cvs 'PIE_FRF-SEK.csv', ou les colonnes sont biens distinctes :
    # Mois	        Moyenne FRA/SEK=	Min FRA/SEK=	Max FRA/SEK=	Nb jours ouvrés
    # 01/09/2019	0.016341	          0.016213	       0.016484	       7
    # 01/08/2019	0.016366	          0.016292	       0.016525	       22
    # 01/07/2019	0.016099	          0.015999	       0.016258	       23
    # ...
    ';' n'est pas séparateur des différents champs et 01/09/2019 n'est pas du format '%d-%m-%Y'.

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

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Detection format mots dans fichier
    Par thais781 dans le forum AppleScript
    Réponses: 4
    Dernier message: 16/10/2013, 12h46
  2. [XL-2007] Format javascript dans fichier texte via urldownloadtofile VBA
    Par patbo2 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 05/10/2009, 12h44
  3. Format décimal dans les fichiers XML
    Par wozzz dans le forum XML/XSL et SOAP
    Réponses: 3
    Dernier message: 31/05/2006, 09h18
  4. récupération des dates d'un fichier
    Par Bleuarff dans le forum Langage
    Réponses: 6
    Dernier message: 22/11/2005, 01h50
  5. Insérer une date au format français dans un champ
    Par EpOnYmE187 dans le forum Installation
    Réponses: 2
    Dernier message: 14/06/2005, 12h09

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