2017-10-16 3 views
1

J'ai deux dataframes:Comment fusionner deux données avec une valeur de tolérance?

df1<- A  C 
     7.629 1 
     5.227 2 
     5.472 3 
     5.386 4 
     5.445 5 

     A  B 
df2<- 7.634 10.0 
     7.732 30.0 
     5.223 33.0 
     5.479 22.0 
     5.390 49.0 
     5.439 53.0 

Je voudrais effectuer une fusion intérieure sur la colonne A avec une valeur de tolérance de ± 0,01 pour obtenir le datafame résultant:

df3<-  A  B  C 
      7.634 10.0  1 
      5.223 33.0  2 
      5.479 22.0  3 
      5.390 49.0  4 
      5.439 53.0  5 

Est-ce possible faire?

(notez que la colonne A de DF3 a des valeurs copiées à partir DF2)

+0

Si ma solution est travaillée après que vous ayez mis à jour les pandas, vous pouvez l'accepter :) – Wen

+0

Salut Wen, j'ai encore du mal à le faire fonctionner, désolé :/... Je reçois l'erreur "Longueur des valeurs ne correspond pas à la longueur de l'index" lors de l'utilisation de "loc" ... – Neko

+0

J'utilise un ensemble différent de données de l'exemple (qui a été fait pour la simplicité) où df2 a 72 lignes, donc il peut y avoir plusieurs valeurs de la colonne B associées aux 5 valeurs dans la colonne A de df1 ... aussi, ma valeur d'erreur est plus comme +/- 0.003, donc je ne peux pas utiliser le premier solution (j'ai juste utilisé ± 0.01 pour la simplicité encore) D: – Neko

Répondre

3

merge_asof semble résoudre votre problème (Recommander 2ème méthode, je l'apprends de Zero ~)

pd.merge_asof(df2.sort_values('A'), df1.sort_values('A'), direction='nearest',on='A').sort_values('C').drop_duplicates('C') 
Out[415]: 
     A C  B 
0 5.227 2 33.0 
1 5.386 4 49.0 
2 5.445 5 53.0 
3 5.472 3 22.0 
4 7.629 1 10.0 

Ou en utilisant IntervalIndex

df2.index = pd.IntervalIndex.from_arrays(df2['A']-0.01,df2['A']+0.01,closed='both') 
df1['B']=df2.loc[df1.A].B.values 
df1['A']=df2.loc[df1.A].A.values 
df1 
Out[450]: 
        A C  B 
[7.619, 7.639] 7.634 1 10.0 
[5.217, 5.237] 5.223 2 33.0 
[5.462, 5.482] 5.479 3 22.0 
[5.376, 5.396] 5.390 4 49.0 
[5.435, 5.455] 5.439 5 53.0 
+0

Les valeurs ne correspondent pas à OP. Vous avez besoin de 'pd.merge_asof (df2.sort_values ​​(par = 'A'), df1.sort_values ​​(par = 'A'), direction = 'plus proche'). Sort_values ​​('C'). Drop_duplicates (sous-ensemble = ['C ']) ' – Zero

+0

got it, le fixer – Wen

+0

@Zero 2ème méthode apprendre de vous ~ :-) – Wen