pandas数据帧中元素之间的浮点精度不同



我正试图从csv中读取一个数据帧,用它进行一些计算,然后将结果导出到另一个csv。在执行此操作时,我注意到值8.1e-202正在更改为8.1000000000000005e-202。但所有其他数字都是正确表示的。

示例:

example.csv如下所示:

id,e-value
ID1,1e-20
ID2,8.1e-202
ID3,9.24e-203

如果我这样做:

import pandas as pd
df = pd.read_csv("example.csv")
df.iloc[1]["e-value"]
>>> 8.1000000000000005e-202
df.iloc[2]["e-value"]
>>> 9.24e-203

为什么8.1e-202被改变而9.24e-203没有?

我试图将pandas使用的数据类型从默认更改为

df["e-value"].dtype
>>> dtype('float64')

numpy数据类型如下:

import numpy as np
df = pd.read_csv("./temp/test", dtype={"e-value" : np.longdouble})

但这只会导致:

df.iloc[1]["e-value"]
>>> 8.100000000000000522e-202

有人能向我解释为什么会发生这种事吗?我无法用任何其他数字复制这个问题。所有大于或小于8.1e-202的东西似乎都能正常工作。

编辑:
指定我的问题。我知道花车并不完美。我的实际问题是,一旦我将数据帧写回csv,结果文件将如下所示:

id,e-value
ID1,1e-20
ID2,8.1000000000000005e-202
ID3,9.24e-203

并且我需要第二行是ID2,8.1e-202
I"固定的";这是在我写csv之前对这一列进行格式化,但我对这种解决方案不满意,因为格式化会将其他元素更改为科学的符号,而它只是一个普通的浮点值。

def format_eval(e):
return "{0:.1e}".format(e)
df["e-value"] = df["e-value"].apply(lambda x: format_eval(x))

浮点数表示并不那么简单。并不是每个实数都可以表示,几乎所有(相对而言(都是近似值。与整数不同,精度各不相同,python确实有一个未定义浮点值的精度。

每个浮点标准都有自己的一组实数,可以精确地表示。周围没有工作。

https://en.wikipedia.org/wiki/Single-precision_floating-point_formathttps://en.wikipedia.org/wiki/IEEE_754-2008_revision

如果问题真的是算术或比较,你应该考虑错误是会增加还是减少。例如,乘以大数字可能会增加表示误差。

此外,在进行比较时,你应该做math.is_close之类的事情。基本上是比较数字之间的距离。

如果你试图表示和运算实数,那就不是无理数。像整数、分数或具有有限数字的十进制数字一样,您也可以考虑强制转换为正确的数字表示形式,如:int、decimal或fraction。

有关进一步的想法,请参阅:https://davidamos.dev/the-right-way-to-compare-floats-in-python/#:~:text=如何%20To%20Compare%20Floats%20in%20Python&text=如果%20abs(a%20%2D%20b(,则rel_tol%20关键字%20参数%20,共%20math。

最新更新