1
votes

Fusionner deux blocs de données et conserver des colonnes uniques

J'ai ces deux blocs de données:

1er df

df3 = pd.merge(df1, df2, on="location", how="right")

2ème df

df3 = pd.merge(df1, df2, on="location", how="left")

Résultat attendu:

Je souhaite utiliser la colonne de localisation de # df1 car elle est plus propre et conserve toutes les autres colonnes. Je n'ai pas besoin des informations de ville, pays dans la colonne de localisation.

    location            Ethnic Origins   Percent(1)  lat       lng
0   Beaches-East York   English          18.9        43.681470  -79.306021
1   Davenport           Portuguese       22.7        43.671561  -79.448293
2   Eglinton-Lawrence   Polish           12.0        43.719265  -79.429765

J'ai essayé plusieurs façons de les fusionner mais en vain.

Ceci renvoie un NaN pour toutes les lignes lat et longues

 #df2 -----

    location                                            lat        lng
0   Beaches—East York, Old Toronto, Toronto, Golde...   43.681470   -79.306021
1   Davenport, Old Toronto, Toronto, Golden Horses...   43.671561   -79.448293
2   Eglinton—Lawrence, North York, Toronto, Golden...   43.719265   -79.429765

Cela renvoie un NaN pour tous les Ethnic et Pourcentage de lignes

#df1 -----

    location            Ethnic Origins       Percent(1)
0   Beaches-East York   English              18.9 
1   Davenport           Portuguese           22.7
2   Eglinton-Lawrence   Polish               12.0


3 commentaires

Si vos lignes sont dans le bon ordre, vous pouvez simplement utiliser pd.concat ([df1, df2], axis = 1)


L'idée de base de pd.merge est qu'il machine des lignes qui ont les mêmes valeurs pour la colonne que vous avez spécifiée. Etant donné que les valeurs de location ne correspondent jamais entre df1 et df2 , les lignes ne sont pas appariées et c'est pourquoi vous obtenez le None. Vous devez donc soit utiliser concat , soit créer une ligne dans df2 qui correspondra à l'emplacement dans df1 (comme suggéré par WeNYoBen, ou plus simplement en appliquant lambda s: s.split (',') [0] à l ' location : cela ne conservera le texte que jusqu'à la première virgule)


@Jalena, vous avez "-" dans df2 et "-" dans df1.


3 Réponses :


1
votes

Nous devrions utiliser findall pour créer la clé

df2['location']=df2.location.str.findall('|'.join(df1.location)).str[0]
df3 = pd.merge(df1, df2, on="location", how="left")


0 commentaires

1
votes

Je suppose que le problème que vous rencontrez est que la colonne sur laquelle vous essayez de fusionner n'est pas la même, c'est-à-dire qu'elle ne trouve pas les valeurs correspondantes dans df2.location à fusionner avec df1 . Essayez d'abord de les modifier et cela devrait fonctionner:

df2["location"] = df2["location"].apply(lambda x: x.split(",")[0])
df3 = pd.merge(df1, df2, on="location", how="left")


3 commentaires

Vous pouvez appliquer "maxsplit = 1" en fractionnement.


@MihailonutDeaconuCeci renvoie une erreur - l'objet 'float' n'a pas d'attribut 'split'


@Jalene split appartient à la classe str , et ne fonctionne que sur les chaînes. Il semble que certaines des valeurs de votre colonne df2.location soient soit de type float , soit une valeur nulle. Vous voudrez peut-être vérifier les valeurs nulles dans la colonne df2.location avant de fusionner: df2 [df2.location.isnull ()]



1
votes

Comme d'autres l'ont noté, le problème est que les colonnes "location" ne partagent aucune valeur. Une solution à cela consiste à utiliser une expression régulière pour se débarrasser de tout ce qui commence par la première virgule et s'étendant jusqu'à la fin de la chaîne:

df3 = pd.merge(df1, df2, on="location", how="left")

En utilisant les données exactes que vous fournissez, cela gagnait toujours t fonctionne parce que vous avez différents types de tirets dans les deux blocs de données. Vous pouvez résoudre ce problème de la même manière (aucune expression régulière n'est nécessaire cette fois):

df2.location = df2.location.replace('—', '-')

Et puis fusionner comme vous l'avez suggéré

df2.location = df2.location.replace(r',.*', '', regex=True)


2 commentaires

J'ai essayé de remplacer le - et le - mais en vain. Si j'utilise inplace = True , cela produit des lignes de NaN.


Cela marche! df2.location = df2.location.replace ("-", "-", regex = True)