J'essaie de fusionner deux dataframes pandas qui ont des lignes en double (ici les lignes constituées de 2 correspondant à «a» et «b») parmi les entrées que j'essaye de fusionner. En conséquence, les pandas prennent un produit cartésien des lignes dupliquées comme indiqué ci-dessous:
In [12]: df_output = pd.DataFrame({'a' : [1, 2, 2], 'b' : [2, 2, 2], 'c' : [3, 6 ...: , 6], 'd' : [np.nan, 2, 5]}) In [13]: df_output Out[13]: a b c d 0 1 2 3 NaN 1 2 2 6 2.0 2 2 2 6 5.0
Le résultat que je souhaite est de ne faire effectuer la fusion qu'une seule fois entre chaque ligne dupliquée, dans l'ordre où ils apparaissent (dans ce cas numériquement par l'indice). Donc, le résultat que j'aimerais avoir est:
In [8]: df1 = pd.DataFrame({'a' : [1, 2, 2], 'b' : [2, 2, 2], 'c' : [3, 6, 6]}) In [9]: df2 = pd.DataFrame({'a' : [2, 2], 'b' : [2, 2], 'd' : [2, 5]}) In [10]: df1.merge(df2, how='outer', on=['a', 'b']) Out[10]: a b c d 0 1 2 3 NaN 1 2 2 6 2.0 2 2 2 6 5.0 3 2 2 6 2.0 4 2 2 6 5.0
Comment puis-je faire cela?
3 Réponses :
Vous avez besoin d'une colonne d'assistance par compteur créé par GroupBy.cumcount
:
df = df1.merge(df2, how='outer', on=['a', 'b', 'g']).drop('g', axis=1) print (df) a b c d 0 1 2 3 NaN 1 2 2 6 2.0 2 2 2 6 5.0
Dernière colonne de suppression g
:
df1 = pd.DataFrame({'a' : [1, 2, 2], 'b' : [2, 2, 2], 'c' : [3, 6, 6]}) df2 = pd.DataFrame({'a' : [2, 2], 'b' : [2, 2], 'd' : [2, 5]}) df1['g'] = df1.groupby(['a', 'b']).cumcount() df2['g'] = df2.groupby(['a', 'b']).cumcount() df = df1.merge(df2, how='outer', on=['a', 'b', 'g']) print (df) a b c g d 0 1 2 3 0 NaN 1 2 2 6 0 2.0 2 2 2 6 1 5.0
drop_duplicates
ne résout-il pas votre problème?
df = df1.merge(df2, how='outer', on=['a', 'b']) df = df.drop_duplicates()
Je pense que cela suffira
df1.merge(df2, how = 'outer').drop_duplicates()
Drop_duplicates ne fera pas le travail?