numpy数组在传递给循环时失去精度,因此无法进行比较。

huangapple go评论91阅读模式
英文:

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

问题

以下是您要翻译的内容:

我有一个函数,它接收一个一维坐标数组作为输入。这些坐标是在字典中定义的分段函数的区间端点,并且也作为输入传递。然而,在进行比较时,数组的值在循环中会改变精度,因此比较不再起作用。这是代码:

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有一个插值函数,但我已经有适应值的方程,并且如果初始数据不好,我可以使用该函数吗?

英文:

I have a function that is passed an array of coordinates in 1D. These are the ends of sections for which piecewise functions have been defined in a dictionary, and also passed in as input. However, when making comparisons, the array values change precision in the loop, and so the comparison is not working anymore. Here is the code:

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[&#39;Name&#39;].values)):
        if data[&#39;Name&#39;][i] != &#39;Totals&#39;and data[&#39;Name&#39;][i] != &#39;Name&#39;:
            cogy.append(data[&#39;cgY&#39;].values[i])
            mass.append(data[&#39;Mass&#39;].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] &gt;= y[j] and cogy[i] &lt; y[j+1]:
                x[i] = wingline[&#39;xy&#39;][j][0] * cogy[i] + wingline[&#39;xy&#39;][j][1]
                z[i] = wingline[&#39;yz&#39;][j][0] * cogy[i] + wingline[&#39;yz&#39;][j][1]
            # print(wingline[&#39;xy&#39;][j],wingline[&#39;yz&#39;][j])
            print(y[j],y[j+1])
        # print(i,x[i],cogy[i],z[i])

The output is as follows:

[ 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

As you can see, the input array, and the values from the loop index don't match, preventing the comparisons from working. How can I make this comparison, or there a better way of implementing this?

I understand that numpy has an interpolate function here, but I already have the equations to fit the values to, and if the input data is not good to begin with, can I use that function?

答案1

得分: 0

由于计算机工作原理的原因,根据这个类似的问题,这是一个已知的问题:https://stackoverflow.com/questions/588004/is-floating-point-math-broken

我的解决方案是使用绝对值比较,正如那个问题的被接受答案所建议的。
以下是编辑后的代码:

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]
英文:

Due to how computers work, this is a known problem according to the this similar question: https://stackoverflow.com/questions/588004/is-floating-point-math-broken

My solution was to use absolute value comparisons, as suggested in the accepted answer to that question.
Here is the edited code:

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] &gt;= 0:
            if abs(cogy[i] - y_coords[j] &gt; 0.0001) and abs(cogy[i] - y_coords[j+1] &lt;= 0.0001):
                x[i] = wingline[&#39;xy&#39;][j][0] * cogy[i] + wingline[&#39;xy&#39;][j][1]
                z[i] = wingline[&#39;yz&#39;][j][0] * cogy[i] + wingline[&#39;yz&#39;][j][1]
        else:
            if abs(cogy[i]) - abs(y_coords[j]) &gt;= 0.0001 and abs(cogy[i]) - abs(y_coords[j+1]) &lt; 0.0001:
                x[i] = -wingline[&#39;xy&#39;][j][0] * cogy[i] + wingline[&#39;xy&#39;][j][1]
                z[i] = -wingline[&#39;yz&#39;][j][0] * cogy[i] + wingline[&#39;yz&#39;][j][1]

huangapple
  • 本文由 发表于 2023年7月31日 22:34:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804640.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定