python - 如何使用 DataFrame 比较两个 CSV 文件并检索不同的单元格?为什么浮点单元格中会出现这么多小数位?

标签 python python-3.x pandas dataframe floating-accuracy

我有一个 CSV 文件,例如此文件 ( example.csv )。

STRING_COL,INT_1,INT_2,FLOAT,INT_3
Hello,9,65151651,3234.54848,7832
This is a string,2,5484651,34.234,-999
Another,2,62189548,51.51658,-999
Test,2,2131514,5.2156,-999
Ham,9,6546548,2.15,-999
String,9,3216546,2.15468,-999

每个单元格都有不同的小数位数。它们也可以是字符串或整数(Int64、Int8,...)。然后我也有一个类似的 CSV,但更改了一些值。我想检查两个文件之间的差异。

因此,我编写了类似于此的代码来逐个单元格地比较值:

import pandas as pd

df = pd.read_csv(
    'example.csv', delimiter=',', comment='#', skip_blank_lines=True,
    verbose=False, engine='python', dtype=str
)
df = df.apply(lambda x: pd.to_numeric(x, errors='ignore', downcast='integer'))

df_2 = pd.read_csv(
    'example_2.csv', delimiter=',', comment='#', skip_blank_lines=True,  # file with small changes
    verbose=False, engine='python', dtype=str
)
df_2 = df_2.apply(lambda x: pd.to_numeric(x, errors='ignore', downcast='integer'))

for i in list(df.index):
    for column in list(df.columns):
        old = df.loc[i, column]
        new = df_2.loc[i, column]
        if old != new:
            print('DIFFERENT VALUE >> INDEX: {} | OLD: {} | NEW: {}'.format(i, old, new))

如果您使用小 CSV 文件运行此示例,我确信它会运行良好。但是对于一个巨大的 CSV 文件,一些奇怪的事情发生了。我不明白为什么有时许多值被截断为这个:

1.6440000000000001  >> original value 1.644
7.7189999999999985  >> original value 7.7189

然后,如果我比较它们,就会发现它们是不同的,但事实并非如此,因为值是相同的。怎么了?有没有办法来解决这个问题?有没有更好的方法将值与 DataFrame 进行比较?

注意:也许我在原始代码的其他部分做错了什么,但我认为我已经编写了最重要和相关的部分。

注 2:我考虑到 !=运算符不能很好地与 NaN 配合使用值(value)观。我用np.isnan检查此更改。

更新。我不需要比较并说“是的,它相等”和“不,它不相等”。我需要逐个单元地检索发生变化的值。

最佳答案

最后我找到了一些可以以适当的方式进行比较的东西:np.isclose() 。我已阅读我发现的重复问题以及有关 epsilon 值的其他一些问题:numpy.finfo() , epsilon

Epsilon: Numbers which differ by less than machine epsilon are numerically the same

    abs(a - b) < epsilon
    absolute(a - b) <= (atol + rtol * absolute(b))      # np.isclose() method

所以我需要做这样的东西。我必须检查如果我在 float32 and float64 or float16 之间进行比较会发生什么

eps64 = np.finfo(np.float64).eps
for col in df.columns:
    np.isclose(
        df[col],
        df_2[col],
        equal_nan=False,
        atol=0.0,
        rtol=eps64
    )

但现在我面临的问题是,如果我想将值复制到其他变量,我会复制不准确的值1.6440000000000001。我现在要做的就是将值转换为 float >> float(1.6440000000000001)

关于python - 如何使用 DataFrame 比较两个 CSV 文件并检索不同的单元格?为什么浮点单元格中会出现这么多小数位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52460740/

相关文章:

python - 如何将正则表达式转换为 NFA?

python - 从 C 导入标准 Python 库

python - Django/mysql中间表不插入数据

python - 从文本文件读取正则表达式时如何防止 Python 转义特殊字符?

python - 如何使用python并行查询数据库

python - 有没有办法让我的 blit 在第一次迭代后重复自身?

arrays - Python Pandas : selecting 1st element in array in all cells

python - 使用带有转义字符的 Pandas 将 csv 转换为 tsv

python - 从 Pandas 中的两个不同行解析日期

python - Pandas - 提取行直到满足条件