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 :

Import .txt vers Panda Dataframe, problème header


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut Import .txt vers Panda Dataframe, problème header
    Bonjour à tous,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
     
    data = pd.read_csv ('G:/work/essai2.txt', delimiter="\t", header=0, index_col = [0], names=["x","y"])
    print(data)
     
    print(data['x'])
    Je souhaiterais construire un histogramme horizontal à partir d'un fichier .txt.

    Comme el fichier contient une colonne de Strings et une colonne de Integer, je pense qu'un dataframe est mieux indiqué qu'un array.
    Je souhaiterais mettre mes contenus de colonne dans des series pour les 'plot'.

    Cependant pour une raison que j'ignore, je n'arrive pas à importer correctement ma donnée et son header.
    Il ne place pas les headers "x" et "y" au même niveau et de fait je ne peux pas sélectionner mes colonnes.

    Pouvez-vous m'éclairer sur ce problème simple ?
    Note : j'ai revérifié mon fichier source, et essayé en txt et csv, je ne vois aucun espace "nuisble"..

    Nom : 1.png
Affichages : 8142
Taille : 15,9 Ko

    Merci par avance,
    Cdt,
    G.

  2. #2
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Je viens de me rendre compte que le problème vient de l'attribut index_col.

    Si je le supprime, j'ai bien mes données en ordre ligne par ligne.
    En revanche, n'existe-t-il pas un moyen de faire comprendre à python que je veux cacher mes index, mais que ma 1ère ligne contient bien mes en-tête ?

    Car si je procède ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
     
    data = pd.read_csv('G:/work/essai2.txt', delimiter="\t", header=0)
    print(data)
     
    print(data['y'])
    print(data['x'])
     
    data_x = data['x']
    print(data_x)
    J'obtiens à la fois ma colonne index et ma colonne 'x'...

  3. #3
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut,

    Il me semble qu'un DataFrame contient obligatoirement des columns et des indexs, que ce soient ceux par défauts ou ceux renseignés. Lorsque l'on affiche (via print) le tableau, les index sont aussi affichés. Je ne pense pas que l'on puisse ne pas les afficher.

    Si vous ne spécifiez pas l'indice de l'argument header, donc en faisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data = pd.read_csv('G:/work/essai2.txt', delimiter="\t")
    Vous devriez obtenir la même chose.

    J

  4. #4
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Merci pour la réponse.

    En effet j'obtiens la même chose.

    Maintenant ma question :
    - Est-ce-que si je stock ma colonne 0 (x) dans une série panda pour plot, va t'il m'afficher les index aussi dans la série ?

    Je vais tester ceci à côté.
    G.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    C'est bon, je m'en suis sorti :

    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
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
     
    data = pd.read_csv('G:/work/essai2.txt', delimiter="\t")
     
    print(data)
    #data2 = data.sort_index(by=['x', 'y'], ascending=[True, False]) #Sort by alphabetical order cause panda detects string inside
    data2 = data.sort_index(by=['y', 'x'], ascending=[True, False]) #Sort from smallest to highest value (initial is highest to smallest)
    print(data2)
     
    data_x = str(data2['x']) #make a panda serie containing STR out of the X column
    data_y = data2['y'] #make a panda serie containing INT out of the Y column
    data_index = data2.iloc[:,0] #make a panda serie containing x with iloc method
    data_index2 = list(data2.index) #make a panda serie containing the index of the whole file. this does support slicing.
     
    freq_series = pd.Series(data_y)

    Maintenant il ne me reste plus qu'à paramétrer le graph, je souhaiterais afficher mes 'x' en valeurs de l'axe Y et mes valeurs 'y' du plus petit à gauche vers le plus grand à droite sur l'axe X
    Je souhaiterais appliquer la suite sur ce modèle :

    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
    plt.figure(figsize=(8, 4)) # adjusting graph size / proportions
    ax = freq_series.plot(kind='barh', label='Filing\nApplications', color='orange')
    ax.set_title("blabla")
    ax.set_xlabel("Years")
    ax.set_ylabel('blabla')
    ax.set_xticklabels(occ) # tickles for X axis
    ax.set_yticklabels(label) # tickles for X axis
     
    rects = ax.patches
     
    # Rotating the xticklabels for years
    for label in ax.get_xmajorticklabels():
        label.set_rotation(30)
        label.set_verticalalignment("top")
     
    # Making the labels
    def autolabel(rects, ax):
        # Get y-axis height to calculate label position from. 
        (x_bottom, x_top) = ax.get_ylim()
        x_height = x_top - x_bottom
     
        for rect in rects:
            height = rect.get_height()
     
            # Fraction of axis height taken up by this rectangle
            p_height = (height / x_height)
     
            # If we can fit the label above the column, do that;
            # otherwise, put it inside the column.
            if p_height > 0.95: # arbitrary; 95% looked good to me.
                label_position = height - (x_height * 0.05)
            else:
                label_position = height + (x_height * 0.01)
     
            ax.text(rect.get_x() + rect.get_width()/2., label_position,
                    '%d' % int(height),
                    ha='right', va='bottom')
     
    autolabel(rects, ax)

  6. #6
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    data_x = str(data2['x']) #make a panda serie containing STR out of the X column
    data_y = data2['y'] #make a panda serie containing INT out of the Y column
    data_index = data2.iloc[:,0] #make a panda serie containing x with iloc method
    data_index2 = list(data2.index) #make a panda serie containing the index of the whole file. this does support slicing.

    freq_series = pd.Series(data_y)
    Je ne vois pas trop ce que vous voulez faire ici. Il faut savoir qu'un DataFrame est composé de Series. Donc quand vous faites:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    freq_series = pd.Series(data_y)
    , c'est pareil que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    freq_series  = data2['y']
    Si je comprends bien là où vous voulez en venir, c'est transformer vos données de sorte à pouvoir faire ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ax = freq_series.plot(kind='barh', label='Filing\nApplications', color='orange')
    Si c'est bien cela, vous pourriez nous donner un extrait des données brutes et un extrait des données travaillées freq_series, pour que l'on se figure un peu mieux la chose

    J

  7. #7
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Merci du retour.

    En fait j'aimerais tout simplement pouvoir produire à partir d'un fichier externe .txt (ou csv) un histogramme horizontal :
    - dont la longueur des barres est égale à ma valeur y
    - dont le set.yticklabels est égale à ma valeur x
    - affichant la valeur de chaque barre en bout de barre
    - dont l'axe x se générerait automatiquement avec un peu d'arithmétique, allant de la valeur la + faible à gauche, jusqu'à la + forte à droite.

    PJ : un fichier. txt template et une image.

    Nom : 1.png
Affichages : 7254
Taille : 11,7 Ko
    Fichiers attachés Fichiers attachés

  8. #8
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut,

    Pour les graphs avec matplotlib je vous conseille d'aller jeter un oeil à la galerie du site. Les exemples sont nombreux et sont d'une aide précieuse pour rapidement atteindre ses objectifs.

    Voici ce que je ferais (en vrac):
    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
    import pandas as pd
    import matplotlib.pyplot as plt
     
    # Import data
    data = pd.read_table('template.txt', sep='\t')
     
    tickers = data['x'].values
     
    # Plot data
    fig, ax = plt.subplots()
    rects = ax.barh(range(len(tickers)), data['y'].values, align='center', color='#4E8DC4', alpha=0.6)
    ax.set_yticks(range(len(tickers)))
    ax.set_yticklabels(tickers)
    ax.set_xlabel('Hmm')
    ax.set_title('title')
     
    # Add label to the right of the bars
    for i, rect in enumerate(rects):
        # Get width of the bar
        xloc = int(rect.get_width()) + 0.5
        # Center the text vertically in the bar
        yloc = rect.get_y() + rect.get_height()/2.0
        label = ax.text(
            xloc, yloc,
            data['y'].values[i],
            horizontalalignment='right',
            verticalalignment='center',
            color='k',
            clip_on=True,
            )
     
    plt.show()
    La partie "import" des données se résume à une ligne finalement. Merci pandas. Pour ce qui est du graph, la difficulté est de placer les labels à droite. Pour cela il faut parcourir chaque barre, déterminer sa largeur et sa position verticale pour connaitre la position du label correspondant. Cela donne ceci (à noter qu'il est possible d'inverser les barres si besoin):
    Nom : bars.png
Affichages : 7213
Taille : 13,6 Ko

    J

  9. #9
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Merci pour ta réponse.

    J'ai adapté ton code sur un fichier plus gros avec une inversion de la table pour avoir les + occurrences les plus fortes en haut.

    Saurais-tu comment je peux corriger :
    - L'espace blanc/vide sur l'axe Y (pourquoi est-il ici ?).
    - Les labels ytickers qui sont parfois longs et sont coupés.

    Merci !

    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
    import pandas as pd
    import matplotlib.pyplot as plt
     
    # Import data
    data = pd.read_table('G:/work/essai2.txt', sep='\t')
     
    # Reverse table from smallest to highest
    data2 = data.sort_index(by=['y', 'x'], ascending=[True, False])
    print(data2)
     
    tickers = data2['x'].values
     
    # Plot data
    fig, ax = plt.subplots()
    rects = ax.barh(range(len(tickers)), data2['y'].values, align='center', color='#4E8DC4', alpha=0.6)
    ax.set_yticks(range(len(tickers)))
    ax.set_yticklabels(tickers)
    ax.set_xlabel('Hmm')
    ax.set_title('title')
     
    # Add label to the right of the bars
    for i, rect in enumerate(rects):
        # Get width of the bar
        xloc = int(rect.get_width()) + 15 #x-dimension label position (the highest, the farthest)
        # Center the text vertically in the bar
        yloc = rect.get_y() + rect.get_height()/3.0
        label = ax.text(
            xloc, yloc,
            data2['y'].values[i],
            horizontalalignment='right',
            verticalalignment='center',
            color='k',
            clip_on=True,
            )
     
    plt.show()
    Nom : 1.png
Affichages : 7185
Taille : 91,4 Ko
    Fichiers attachés Fichiers attachés

  10. #10
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Effectivement, c'est pas terrible. Le soucis avec l'espace en trop vient que matplotlib choisi lui-même le range de valeurs en abscisse et en ordonnée à afficher pour que toutes le données soient visibles. En l'occurrence, pour l'axe y il faut limiter l'affichage à des valeurs entre -1 et N, N le nombre de barres:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ax.set_ylim((-1, len(tickers)))
    Il existe une commande "magique" pour forcer matplotlib a "optimiser" l'affichage et éviter ce problème de labels en dehors de la fenêtre:
    Le graph produit reste assez moche, mais bon en modifiant quelques paramètres à la main ça devrait le faire!

    J

  11. #11
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Ca tourne niquel.

    Tu penses quoi en particulier pour améliorer ?

    Merci,
    F.

  12. #12
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut,

    Un alias pour les noms comme MSFT pour "MICROSOFT TECHNOLOGY LICENSING", modifier la couleur (peut-être voir du côté de seaborn?),.. Mettre une grille en arrière plan? Passer en échelle log sur l'abscisse?

  13. #13
    Membre à l'essai
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2014
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2014
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    D'accord, oui je vois.

    Venant de VBA, je me mets doucement à la dataviz sous python.
    Il y encore pas mal de choses que je découvre.

    Est-il possible de générer un diagramme avec matplotlib.plt, et d'y affecter des objets méthodes venant de Seaborn ou Bokeh etc.. ?

    F.

    Note : ma version finale

    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
    import pandas as pd
    import matplotlib.pyplot as plt
     
    # Import data
    data = pd.read_table('G:/work/essai2.txt', sep='\t')
     
    # Reverse table from smallest to highest
    data2 = data.sort_index(by=['y', 'x'], ascending=[True, False])
    print(data2)
     
    tickers = data2['x'].values
     
    # Plot data
    fig, ax = plt.subplots(figsize=(10,11))
    rects = ax.barh(range(len(tickers)), data2['y'].values, align='center', color='#4E8DC4', alpha=0.6)
    ax.set_yticks(range(len(tickers)))
    ax.set_yticklabels(tickers)
    ax.set_xlabel('Hmm')
    ax.set_title('title')
    ax.set_ylim((-1, len(tickers))) # allows to auto-size Y axis depending of [-1:N] bars
    ax.grid()
     
    # Rotating the xticklabels for patents volume
    for label in ax.get_xmajorticklabels():
        label.set_rotation(30)
        label.set_verticalalignment("top")
     
    # Add label to the right of the bars
    for i, rect in enumerate(rects):
        # Get width of the bar
        xloc = int(rect.get_width()) + 35 #x-dimension label position (the highest, the farthest)
        # Center the text vertically in the bar
        yloc = rect.get_y() + rect.get_height()/3.0 #y-dimension label position
        label = ax.text(
            xloc, yloc,
            data2['y'].values[i],
            horizontalalignment='right',
            verticalalignment='center',
            color='k',
            clip_on=True,
            )
     
     
    plt.tight_layout() # allows to autosize-labels & tickers to fit diagram
    plt.show()
    Nom : 1.png
Affichages : 7244
Taille : 189,5 Ko

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/03/2011, 10h47
  2. [XL-2007] Import .txt vers .xls par VB
    Par Loupire dans le forum Macros et VBA Excel
    Réponses: 20
    Dernier message: 28/01/2010, 10h46
  3. Import txt vers table
    Par bennyben87 dans le forum Administration
    Réponses: 4
    Dernier message: 18/03/2009, 15h22
  4. Problème Format Numérique lors d'import txt
    Par clemasson dans le forum Access
    Réponses: 3
    Dernier message: 11/10/2006, 12h31
  5. Problème d'importation .xls vers Access
    Par PsykotropyK dans le forum Access
    Réponses: 1
    Dernier message: 06/09/2006, 17h31

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