Pandas合并DataFrame未匹配全部行问题求助
浮点数精度问题导致Pandas Merge匹配失败
问题出在浮点数的精度误差上。虽然你看到的-410372.62在两个DataFrame里显示一致,但计算机存储浮点数时,这类十进制小数无法被二进制精确表示,经过groupby.sum()计算后,bankDF里的这个金额可能已经带上了微小尾差(比如实际是-410372.6200000001或-410372.6199999999),而glDF里的是原始的-410372.62,导致精确匹配时无法对应。
验证这个问题很简单,你可以打印两个DataFrame中该金额的精确值:
print(bankDF[bankDF['post date'] == '2022-05-04']['amount'].iloc[0]) print(glDF[glDF['amount'] == -410372.62]['amount'].iloc[0])
大概率会看到两者的精确值存在细微差异。
解决方法有几种:
- 对金额字段进行四舍五入,保留两位小数(最直接的解决方案):
bankDF['amount'] = bankDF['amount'].round(2) glDF['amount'] = glDF['amount'].round(2) matchedGL = pd.merge(bankDF, glDF, on='amount', suffixes=("_left", "_right")) - 使用
numpy.isclose做近似匹配(适合无法直接四舍五入的场景):import numpy as np # 先交叉连接所有行,再筛选近似相等的记录 matchedGL = pd.merge(bankDF, glDF, how='cross') matchedGL = matchedGL[np.isclose(matchedGL['amount_x'], matchedGL['amount_y'], atol=1e-6)] - 转换为
Decimal类型处理精确小数(适合对精度要求极高的场景):from decimal import Decimal, getcontext getcontext().prec = 10 bankDF['amount'] = bankDF['amount'].apply(lambda x: Decimal(str(x))) glDF['amount'] = glDF['amount'].apply(lambda x: Decimal(str(x))) matchedGL = pd.merge(bankDF, glDF, on='amount', suffixes=("_left", "_right"))
另外,你代码里的bankDF['amount type'] = bankDF['amount'].dtypes这行冗余且无意义——dtypes返回的是整个列的数据类型,所以这列所有值都会是float64,可以直接删掉。
内容的提问来源于stack exchange,提问作者jpshank
相关产品推荐
相关产品推荐

