将Pandas DataFrame按浮点数列合并

16
我有两个数据框,正试图将它们合并。
数据框 A:
    col1    col2    sub    grade
0   1       34.32   x       a 
1   1       34.32   x       b
2   1       34.33   y       c
3   2       10.14   z       b
4   3       33.01   z       a

数据框 B:
    col1    col2    group   ID
0   1       34.32   t       z 
1   1       54.32   s       w
2   1       34.33   r       z
3   2       10.14   q       z
4   3       33.01   q       e

我想按照col1和col2合并。我已经使用以下语法进行了pd.merge:
pd.merge(A, B, how = 'outer', on = ['col1', 'col2'])

然而,我认为由于许多行被删除,使用col2的浮点值连接时遇到了问题。是否有办法使用np.isclose来匹配col2的值?当我在任一数据框中引用col2的特定值的索引时,该值比数据框中显示的小数位数多得多。
我希望结果是:
    col1   col2   sub   grade   group    ID
0   1      34.32  x     a       t        z
1   1      34.32  x     b       s        w
2   1      54.32  s     w       NaN      NaN
3   1      34.33  y     c       r        z
4   2      10.14  z     b       q        z
5   3      33.01  z     a       q        e

展示预期结果的样式应该是怎样的 - RomanPerekhrest
我已经编辑了帖子以反映所需的输出。 - Megan
@Megan 在你的连接操作中,你已经删除了一些行。请查看我的答案,了解如何基于两列进行合并。在合并后,你可以应用额外的逻辑。 - Mohammad Yusuf
@MohammadYusufGhazi 我编辑了帖子以添加之前遗漏的列,但我不确定您在合并后应用其他逻辑的意思。 - Megan
3个回答

13

您可以使用一点小技巧 - 将多个浮点列乘以一些常数,如1001000 ...,将列转换为int合并最后再除以常数:

N = 100
#thank you koalo for comment
A.col2 = np.round(A.col2*N).astype(int) 
B.col2 = np.round(B.col2*N).astype(int) 
df = pd.merge(A, B, how = 'outer', on = ['col1', 'col2'])
df.col2 = df.col2 / N
print (df)
   col1   col2  sub grade group ID
0     1  34.32    x     a     t  z
1     1  34.32    x     b     t  z
2     1  34.33    y     c     r  z
3     2  10.14    z     b     q  z
4     3  33.01    z     a     q  e
5     1  54.32  NaN   NaN     s  w

1
哦,使用十进制进行连接不准确吗? - Mohammad Yusuf
是的,这是可能的,但我认为这样做效率不高,请参见此评论 - jezrael
1
不错的方法,但由于舍入误差会导致更微妙的错误。最好使用A.col2 = np.round(A.col2*N).astype(int)。 - koalo
@koalo - 非常感谢,我已将其添加到答案中。 - jezrael
2020年更新:现在您可以使用np.round(col, decimals=2)。不确定以前是否不可能,但对我来说效果很好,看起来更简洁 :) - Sam
1
解决方案并不总是有效的。像14.49999和15.500001这样的两个数字分别四舍五入为14和15。 - honglei

1

我曾经遇到过类似的问题,需要在数千个浮点列和没有标识符的情况下确定匹配行。这种情况很困难,因为由于四舍五入,值可能会略微变化。

在这种情况下,我使用了scipy.spatial.distance.cosine来获取行之间的余弦相似度。

from scipy import distance

threshold = 0.99999
similarity = 1 - spatial.distance.cosine(row1, row2)

if similarity >= threshold:
    # it's a match
else:
    # loop and check another row pair

如果存在重复或非常相似的行,这种方法将无法生效,但是当您有大量浮点列且行数不太多时,它能够很好地工作。

0
假设列(col2)有n个十进制数。
A.col2 = np.round(A.col2, decimals=n)
B.col2 = np.round(B.col2, decimals=n)
df = A.merge(B, left_on=['col1', 'col2'], right_on=['col1', 'col2'])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接