使用Data Compy比较Decimal值时如何区分128.12与128.1200
解决Data Compy无法区分Decimal数值128.12与128.1200的问题
Data Compy默认对Decimal类型的比较是基于数值相等性,所以会判定128.12和128.1200为相同值。要让工具识别二者的小数位数差异,可以试试以下几种方案:
方案1:直接以字符串类型读取并比较
如果你的数据源(比如数据库、CSV)中原始值就是带不同小数位数的字符串,读取时直接将对应列指定为字符串类型,避免解析为Decimal后丢失格式信息。
比如用Pandas读取CSV时:
import pandas as pd from datacompy import Compare # 读取时指定目标列为字符串 df1 = pd.read_csv('file1.csv', dtype={'decimal_col': str}) df2 = pd.read_csv('file2.csv', dtype={'decimal_col': str}) # 执行比较 compare = Compare(df1, df2, on='id', compare_columns=['decimal_col']) print(compare.report())
注意:如果已经将数据解析为Decimal类型,再转字符串会丢失小数位数(比如str(Decimal('128.1200'))会返回'128.12'),这种转换方式无效,必须从源头保留字符串格式。
方案2:自定义Decimal比较函数
利用Data Compy的custom_comparisons参数,编写一个同时检查数值和小数位数的比较函数:
from datacompy import Compare from decimal import Decimal import pandas as pd # 构造测试数据 df1 = pd.DataFrame({'id': [1], 'decimal_col': [Decimal('128.12')]}) df2 = pd.DataFrame({'id': [1], 'decimal_col': [Decimal('128.1200')]}) # 自定义比较函数:数值相等且小数位数(scale)一致才判定为相同 def compare_decimal_with_scale(a, b): if a != b: return False # 检查Decimal的scale属性(小数位数) return a.as_tuple().scale == b.as_tuple().scale # 执行自定义比较 compare = Compare( df1, df2, on='id', compare_columns=['decimal_col'], custom_comparisons={'decimal_col': compare_decimal_with_scale} ) # 查看结果,此时128.12和128.1200会被判定为不同 print(compare.report())
这个函数先判断数值是否相等,若相等再检查两个Decimal对象的scale(小数位数)是否一致,从而区分开128.12(scale=2)和128.1200(scale=4)。
方案3:格式化Decimal为固定小数位的字符串
如果必须从Decimal转换为字符串,可通过格式化强制保留所有小数位:
# 将Decimal格式化为带4位小数的字符串(根据你的需求调整位数) df1['decimal_str'] = df1['decimal_col'].apply(lambda x: format(x, '.4f')) df2['decimal_str'] = df2['decimal_col'].apply(lambda x: format(x, '.4f')) # 比较格式化后的字符串列 compare = Compare(df1, df2, on='id', compare_columns=['decimal_str'])
这种方式适合你明确知道需要保留的小数位数的场景。
内容的提问来源于stack exchange,提问作者Vijaya Sai
相关产品推荐
相关产品推荐

