如何修复产生不精确结果的numpy floatingpoint操作?

2024-10-04 01:33:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要从知道样本大小的相对频率中重建绝对频率。在

这应该很容易,但是绝对频率和样本大小是numpy.int64,相对频率是numpy.float64。在

我知道浮点十进制值通常没有精确的二进制表示,我们可能会遇到一些精度损失。似乎是这样,浮点运算产生了意想不到的结果,我不能相信重建的绝对频率。在

复制错误的示例代码:

import pandas as pd
import numpy as np

absolutes = np.arange(100000, dtype=np.int64) #numpy.int64
sample_size = absolutes.sum() # numpy.int64
relatives = absolutes / sample_size #float64

# Rebuilding absolutes from relatives

rebuilt_float = relatives * sample_size #float64
rebuilt_int = rebuilt_float.astype(np.int64)

df = pd.DataFrame({'absolutes': absolutes,
                   'relatives': relatives,
                   'rebuilt_float': rebuilt_float,
                   'rebuilt_int': rebuilt_int})

df['check_float'] = df['absolutes'] == df['rebuilt_float']
df['check_int'] = df['absolutes'] == df['rebuilt_int']

print('Failed FLOATS: ', len(df[df['check_float'] == False]))
print('Failed INTS:', len(df[df['check_int'] == False]))
print('Sum of FLOATS:', df['rebuilt_float'].sum())
print('Sum of INTS:', df['rebuilt_int'].sum())

有没有可能不用把每个数字都转换成十进制数就可以用numpy来解决这个问题?在


Tags: samplenumpydfsizechecknpfloatint
2条回答

如果在转换为整数之前对重新生成的值进行四舍五入,则会得到零个失败的整数。也就是说,使用

rebuilt_int = np.round(rebuilt_float).astype(np.int64)

然后输出

^{pr2}$

np.isclose(df['absolutes'], df['rebuilt_float'], atol=.99999)

^{}是一个不精确的fp感知比较。它有一个额外的参数atol和{},用于相对和绝对公差。在

您可以通过更改atol来查看您消除了多少个舍入错误:

>>> len(np.where( np.isclose(df['absolutes'], df['rebuilt_int'], atol=.99999) == False )[0])
0
>>> len(np.where( np.isclose(df['absolutes'], df['rebuilt_int'], atol=.5) == False )[0])
2767
>>> len(np.where( np.isclose(df['absolutes'], df['rebuilt_int'], atol=1) == False )[0])
0

相关问题 更多 >