首页 > 解决方案 > 如何获取值不能被 0.01 整除的行 - 浮点运算的潜在问题

问题描述

我有一个带有浮点值的熊猫系列,如下所示:

s = pd.Series({0: 899.0,
  1: 899.0,
  2: 1099.0,
  3: 279.29998779296875,
  4: 2598.833251953125,
  5: 499.1666564941406,
  6: 1709.050048828125,
  7: 279.29998779296875,
  8: 999.0,
  9: 1498.9949951171875}, name="var")

我很想获得不能被 0.01 整除的所有值的索引,所以我尝试定义mask = (100 * s % 1) > 0,这与提供的示例系列效果相当好:

s[mask] 
3     279.299988
4    2598.833252
5     499.166656
6    1709.050049
7     279.299988
9    1498.994995
Name: var, dtype: float64

s[~mask]
0     899.0
1     899.0
2    1099.0
8     999.0
Name: var, dtype: float64

但是,s这里提供的只是更大数据集的一个样本,当我在原始系列上做同样的事情时,maskfor的值1709.050049False,这表明这些0049数字只是 number 的浮点表示问题1709.05,它是这样提取的当我s使用方法从原始数据创建时pd.Series.to_dict()。因此,我想知道我掩盖不可被0.01( mask = (100 * s % 1) > 0) 整除的数字的方法是否正确。如果不是,该解决方案出了什么问题,我们如何正确掩盖这些值?

标签: pythonpandasfloating-pointprecision

解决方案


你可以通过设置一个参数来实现你想要的np.isclosertol

s = pd.Series({
    0: 898.999998,
    1: 899.0,
    2: 1099.0,
    3: 279.29998779296875,
    4: 2598.833251953125,
    5: 499.1666564941406,
    6: 1709.050048828125,
    7: 279.29998779296875,
    8: 999.0,
    9: 1498.9949951171875,
    10: 326.78}
    , name="var")

tolerance = 1e-12
mask = np.isclose(s, s.round(2),rtol = tolerance)
s[mask]
1      899.00
2     1099.00
8      999.00
10     326.78
Name: var, dtype: float64

推荐阅读