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 :

Merge Dataframe avec pandas, sans dupliquer les colonnes


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Homme Profil pro
    Éternel universitaire
    Inscrit en
    Avril 2012
    Messages
    421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Éternel universitaire

    Informations forums :
    Inscription : Avril 2012
    Messages : 421
    Par défaut Merge Dataframe avec pandas, sans dupliquer les colonnes
    Bonjour à tous,

    J'essaye d’agglomérer des données assez disparates contenues dans une dizaine de fichiers csv. Ces fichiers contiennent approximativement 100 colonnes, mais cela varie. La grande majorité de ces colonnes sont redondantes d'un fichier à l'autre (mais pas toutes!). Cependant, elles ont toutes une colonne en commun, qu'on nomme 'date_time' ici, qui est utilisée comme point d'encrage pour l'agglomération des dataframes. Lorsque j'effectue un pandas.merge() entre deux dataframes qui ont une colonne en commun (imaginons potato), au lieu d'ajouter les nouvelles données à la colonne existante, cette colonne est dupliquée et renommée automatiquement (potato_x, potato_y). Comment éviter la duplication des colonnes ?
    On peut résumer mon problème avec le petit exemple ci-dessous.

    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
    # Reference dataframe
    df = pd.DataFrame({'date_time':['2018-06-01 00:00:00','2018-06-01 00:30:00','2018-06-01 01:00:00','2018-06-01 01:30:00']})
     
    # Dataframes to merge to reference dataframe
    df1 = pd.DataFrame({'date_time':['2018-06-01 00:30:00','2018-06-01 01:00:00'],
                    'potato':[13,21]})
     
    df2 = pd.DataFrame({'date_time':['2018-06-01 01:30:00','2018-06-01 02:00:00','2018-06-01 02:30:00'],
                    'carrot':[14,8,32]})
     
    df3 = pd.DataFrame({'date_time':['2018-06-01 01:30:00','2018-06-01 02:00:00'],
                    'potato':[27,31], 'zucchini':[11,1]})
     
     
    df = df.merge(df1, how='left', on='date_time')
    df = df.merge(df2, how='left', on='date_time')
    df = df.merge(df3, how='left', on='date_time')
    ce qui donne comme résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    date_time                 potato_x  carrot  potato_y  zucchini
    0  2018-06-01 00:00:00       NaN     NaN       NaN       NaN
    1  2018-06-01 00:30:00      13.0     NaN       NaN       NaN
    2  2018-06-01 01:00:00      21.0     NaN       NaN       NaN
    3  2018-06-01 01:30:00       NaN    14.0      27.0      11.0
    alors que je voudrais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    date_time                 potato  carrot   zucchini
    0  2018-06-01 00:00:00       NaN     NaN       NaN
    1  2018-06-01 00:30:00      13.0     NaN       NaN
    2  2018-06-01 01:00:00      21.0     NaN       NaN
    3  2018-06-01 01:30:00      27.0    14.0       11.0
    Merci beaucoup !

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    149
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2008
    Messages : 149
    Par défaut
    Il faut utiliser un stratagème expliqué dans http://raju.shoutwiki.com/wiki/Manip..._with_new_data (remplacer, éliminer puis renommer)

    Avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    df = pd.DataFrame({'date_time':['2018-06-01 00:00:00','2018-06-01 00:30:00','2018-06-01 01:00:00','2018-06-01 01:30:00','2018-06-01 02:00:00']})
    puisqu'il y a '2018-06-01 02:00:00' et 2 valeurs de potato dans df3

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    df.loc[df['potato_y'].isna(), 'potato_y'] = df['potato_x']
    df.drop(['potato_x'], axis=1, inplace=True)
    df.rename(columns={'potato_y':'potato'}, inplace=True)
    print(df)
         date_time           carrot  potato  zucchini
    0  2018-06-01 00:00:00     NaN     NaN       NaN
    1  2018-06-01 00:30:00     NaN     13.0      NaN
    2  2018-06-01 01:00:00     NaN     21.0      NaN
    3  2018-06-01 01:30:00    14.0     27.0      11.0
    4  2018-06-01 02:00:00     8.0     31.0      1.0
    5  2018-06-01 02:30:00    32.0     NaN       NaN

  3. #3
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut


    Avec concat, une seule colonne potato mais c'est date_time qui est multiple :

    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
    result = pd.concat([df, df1, df2, df3], axis=0, sort=False)
     
    print(result)
     
    '''
                 date_time  potato  carrot  zucchini
    0  2018-06-01 00:00:00     NaN     NaN       NaN
    1  2018-06-01 00:30:00     NaN     NaN       NaN
    2  2018-06-01 01:00:00     NaN     NaN       NaN
    3  2018-06-01 01:30:00     NaN     NaN       NaN
    0  2018-06-01 00:30:00    13.0     NaN       NaN
    1  2018-06-01 01:00:00    21.0     NaN       NaN
    0  2018-06-01 01:30:00     NaN    14.0       NaN
    1  2018-06-01 02:00:00     NaN     8.0       NaN
    2  2018-06-01 02:30:00     NaN    32.0       NaN
    0  2018-06-01 01:30:00    27.0     NaN      11.0
    1  2018-06-01 02:00:00    31.0     NaN       1.0
    '''
    EDIT : la solution du message précédent fonctionne en remplaçant how="left par how='outer' :

    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
    df = df.merge(df1, how='outer', on='date_time')
    df = df.merge(df2, how='outer', on='date_time')
    df = df.merge(df3, how='outer', on='date_time')
     
    df.loc[df['potato_y'].isna(), 'potato_y'] = df['potato_x']
    df.drop(['potato_x'], axis=1, inplace=True)
    df.rename(columns={'potato_y': 'potato'}, inplace=True)
    print(df)
     
    '''
         date_time           carrot  potato  zucchini
    0  2018-06-01 00:00:00     NaN     NaN       NaN
    1  2018-06-01 00:30:00     NaN     13.0      NaN
    2  2018-06-01 01:00:00     NaN     21.0      NaN
    3  2018-06-01 01:30:00    14.0     27.0      11.0
    4  2018-06-01 02:00:00     8.0     31.0      1.0
    5  2018-06-01 02:30:00    32.0     NaN       NaN
    '''

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

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

    Citation Envoyé par thecrazydonut Voir le message
    Comment éviter la duplication des colonnes ?
    En utilisant .combine_first qui est juste là pour çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    df = df.merge(df1, how='left', on='date_time')
    ## df = df.merge(df2, how='left', on='date_time')
    ## df = df.merge(df3, how='left', on='date_time')
    df = df.combine_first(df2)
    df = df.combine_first(df3)
    print(df)
    sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       carrot            date_time  potato  zucchini
    0    14.0  2018-06-01 00:00:00    27.0      11.0
    1     8.0  2018-06-01 00:30:00    13.0       1.0
    2    32.0  2018-06-01 01:00:00    21.0       NaN
    3     NaN  2018-06-01 01:30:00     NaN       NaN
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    [...]sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       carrot            date_time  potato  zucchini
    0    14.0  2018-06-01 00:00:00    27.0      11.0
    1     8.0  2018-06-01 00:30:00    13.0       1.0
    2    32.0  2018-06-01 01:00:00    21.0       NaN
    3     NaN  2018-06-01 01:30:00     NaN       NaN
    - W
    Le résultat n'est pas bon du tout, mélange des horaires et il manque potato 31 !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    '''
         date_time           carrot  potato  zucchini
    0  2018-06-01 00:00:00     NaN     NaN       NaN
    1  2018-06-01 00:30:00     NaN     13.0      NaN
    2  2018-06-01 01:00:00     NaN     21.0      NaN
    3  2018-06-01 01:30:00    14.0     27.0      11.0
    4  2018-06-01 02:00:00     8.0     31.0      1.0
    5  2018-06-01 02:30:00    32.0     NaN       NaN
    '''

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 738
    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 738
    Par défaut
    Citation Envoyé par danielhagnoul Voir le message
    Le résultat n'est pas bon du tout, mélange des horaires et il manque potato 31 !
    Oops!: oui tu as raison, il faut qu'on ait les mêmes lignes pour le faire. Désolé.
    J'ai oublié d'ajouter des index:

    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
    import pandas as pd
     
    # Reference dataframe
    df = pd.DataFrame({'date_time':['2018-06-01 00:00:00','2018-06-01 00:30:00','2018-06-01 01:00:00','2018-06-01 01:30:00']})
     
    # Dataframes to merge to reference dataframe
    df1 = pd.DataFrame({'date_time':['2018-06-01 00:30:00','2018-06-01 01:00:00'],
                    'potato':[13,21]})
     
    df2 = pd.DataFrame({'date_time':['2018-06-01 01:30:00','2018-06-01 02:00:00','2018-06-01 02:30:00'],
                    'carrot':[14,8,32]})
     
    df3 = pd.DataFrame({'date_time':['2018-06-01 01:30:00','2018-06-01 02:00:00'],
                    'potato':[27,31], 'zucchini':[11,1]})
     
    df = df.merge(df1, how='left', on='date_time')
    df.set_index('date_time', inplace=True)
     
    for z in df2, df3:
        z.set_index('date_time', inplace=True)
        df = df.combine_first(z)    
     
    print(df)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
                         carrot  potato  zucchini
    date_time
    2018-06-01 00:00:00     NaN     NaN       NaN
    2018-06-01 00:30:00     NaN    13.0       NaN
    2018-06-01 01:00:00     NaN    21.0       NaN
    2018-06-01 01:30:00    14.0    27.0      11.0
    2018-06-01 02:00:00     8.0    31.0       1.0
    2018-06-01 02:30:00    32.0     NaN       NaN
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre chevronné
    Homme Profil pro
    Éternel universitaire
    Inscrit en
    Avril 2012
    Messages
    421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Éternel universitaire

    Informations forums :
    Inscription : Avril 2012
    Messages : 421
    Par défaut
    Finalement, c'était moins trivial que ce que j'avais imaginé. Merci beaucoup pour le coup de main !

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

Discussions similaires

  1. [AC-2016] Champs table 'compléments' liée en colonne sans dupliquer les lignes
    Par Faridpo dans le forum Requêtes et SQL.
    Réponses: 7
    Dernier message: 02/01/2018, 23h29
  2. Réponses: 6
    Dernier message: 02/03/2013, 01h15
  3. Moyenne sans compter les colonnes cachées
    Par goats dans le forum Excel
    Réponses: 4
    Dernier message: 17/10/2012, 17h16
  4. Réponses: 4
    Dernier message: 22/06/2010, 11h03
  5. [12.5] Exporter le resultat d'une procédure sans afficher les colonnes
    Par bossun dans le forum Adaptive Server Enterprise
    Réponses: 7
    Dernier message: 07/04/2010, 15h39

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