numpy 数组在传递到循环时会失去精度,因此比较不起作用

numpy arrays losing precision when passed to a loop, so comparisons aren't working

提问人:keg504 提问时间:7/31/2023 最后编辑:hpauljkeg504 更新时间:8/2/2023 访问量:73

问:

我有一个函数,它传递了一个一维坐标数组。这些是已在字典中定义分段函数的部分的末尾,也作为输入传入。但是,在进行比较时,数组值会更改循环中的精度,因此比较不再起作用。代码如下:

def parse_mass_data(mass_prop_file, slices, wingline, y_coords):
    data = pd.read_csv(mass_prop_file, delim_whitespace=True,index_col=False, skiprows = 10, skipfooter=(slices+5))
    cogy = []
    mass = []
    y = y_coords.astype(np.float64)
    print(y)
    for i in range(len(data['Name'].values)):
        if data['Name'][i] != 'Totals'and data['Name'][i] != 'Name':
            cogy.append(data['cgY'].values[i])
            mass.append(data['Mass'].values[i])

    cogy = np.array(list(map(float,cogy)))
    mass = np.array(list(map(float,mass)))
    x = np.zeros(len(mass))
    z = np.zeros(len(mass))

    for i in range(len(mass)):
        for j in range(len(y_coords)-1):
            if cogy[i] >= y[j] and cogy[i] < y[j+1]:
                x[i] = wingline['xy'][j][0] * cogy[i] + wingline['xy'][j][1]
                z[i] = wingline['yz'][j][0] * cogy[i] + wingline['yz'][j][1]
            # print(wingline['xy'][j],wingline['yz'][j])
            print(y[j],y[j+1])
        # print(i,x[i],cogy[i],z[i])

输出如下:

[ 0.  6. 10.]
0.0 5.999999999999999
5.999999999999999 9.999999999999998
0.0 5.999999999999999
5.999999999999999 9.999999999999998
0.0 5.999999999999999
5.999999999999999 9.999999999999998
0.0 5.999999999999999
5.999999999999999 9.999999999999998

如您所见,输入数组和循环索引中的值不匹配,导致比较无法进行。我怎样才能进行这种比较,或者有更好的方法来实现这一点?

我知道numpy在这里有一个插值函数,但是我已经有了拟合值的方程式,如果输入数据一开始就不好,我可以使用该函数吗?

python pandas numpy 精度

评论

5赞 jared 7/31/2023
它们确实匹配,只是数值精度。这就是使用浮点数时发生的情况。
1赞 user19077881 7/31/2023
请参阅有关以二进制形式存储十进制浮点值所引起的问题的链接。isClose 函数可用于比较。
0赞 hpaulj 7/31/2023
您有几个 pandas 数据帧,并且 .dtypes是什么?如果列 dtype 已经是浮点的,你就不需要这些东西了。浮点数上的“>=”类比较是不可靠的。如果你能使用整数,那就更好了。datawinglinemap(float, ...)
0赞 keg504 8/1/2023
@jared 所以 6 的 numpy 表示。不是整数吗?
1赞 chrslg 8/1/2023
@keg504 当您显式将其转换为类型时,不会,否np.float64

答:

0赞 keg504 8/1/2023 #1

由于计算机的工作方式,这是一个已知的问题,根据这个类似的问题:浮点数学坏了吗?

我的解决方案是使用绝对值比较,正如该问题的公认答案中所建议的那样。 以下是编辑后的代码:

mass = np.array(list(map(float,mass)))
x = np.zeros(len(mass))
z = np.zeros(len(mass))

for i in range(len(mass)):
    for j in range(len(y_coords)-1):
        if cogy[i] >= 0:
            if abs(cogy[i] - y_coords[j] > 0.0001) and abs(cogy[i] - y_coords[j+1] <= 0.0001):
                x[i] = wingline['xy'][j][0] * cogy[i] + wingline['xy'][j][1]
                z[i] = wingline['yz'][j][0] * cogy[i] + wingline['yz'][j][1]
        else:
            if abs(cogy[i]) - abs(y_coords[j]) >= 0.0001 and abs(cogy[i]) - abs(y_coords[j+1]) < 0.0001:
                x[i] = -wingline['xy'][j][0] * cogy[i] + wingline['xy'][j][1]
                z[i] = -wingline['yz'][j][0] * cogy[i] + wingline['yz'][j][1]

评论

1赞 kubatucka 8/4/2023
嗨,您了解问题并提出合理的解决方案。我建议你看看np.allclose/np.isclose,它们是解决OP面临的确切问题的内置函数。
0赞 keg504 8/5/2023
谢谢,我不知道那个功能,下次我会用到它!