numpy.vstack 失去精度 float16

numpy.vstack losing precision float16

提问人:Joao Victor 提问时间:6/4/2022 最后编辑:Joao Victor 更新时间:6/5/2022 访问量:181

问:

我正在尝试仅使用一位数字作为精确数字来执行线性回归的精确计算。没有 numpy,它可以正常工作,但 numpy 对于大量项目表现更好,这就是我需要使用 numpy 的原因。 但问题是,当我为 X 轴构建矩阵时,我失去了我的十进制精度,如下图所示。

我该如何解决?我的意思是,对于矩阵变量,只返回一位数字作为精确数字。

import numpy as np
import pandas as pd

dataset = [[17.3,71.7],[19.3,48.3],[19.5,88.3]]
df = pd.DataFrame({
    'force': [item[0] for item in dataset],
    'push_up':[item[1] for item in dataset]
})

df_x = np.array([item for item in df['force']],dtype=np.float16)
df_y = np.array([item for item in df['push_up']],dtype=np.float16)

print([np.round(item, decimals=1) for item in df['force']])
#check precision

#here is the issue! the return lose my 1 decimal point precision. 
# notice !No matter if I use this printed array above.
# also tried using this array construction to reconvert to 1 decimal precision but no success
#print( [np.float16(np.format_float_positional(item, precision=1)) for item in df['force']] )


matrix = np.vstack([df_x, np.ones(len(df_x))]).T
print(matrix[0][0])
#this print "17.296875" that is totally different from 17.3
#print(matrix[2][0]) #uncomment this to see that the half precision is not lost at all
python numpy 精度 浮点精度 floating-accuracy

评论

2赞 Eric Postpischil 6/4/2022
17.296875 是最接近 17.3 的。在 17 的比例下,指数为 4,因此数字表示为 F•2^4,其中 F 是以“1”开头的 12 位二进制数字。最接近 17.3 的值是 1.00010100110•2^4,即 17.296875。下一个更高的可表示值是 1.00010100111•2^4 = 17.3046875,比 17.3 更远。将 17.3 放入数组的那一刻,它就变成了 17.296875。这不是由转置引起的。float16float16
0赞 Joao Victor 6/4/2022
明白了!因此,必须使用 dtype=np.float64 来跟上精度。
0赞 hpaulj 6/4/2022
还要注意 dtype 的np.ones(len(df_x))
1赞 CJR 6/5/2022
回顾一下浮点数的实际含义以及精度在这种上下文中的含义将是有用的

答:

1赞 hpaulj 6/4/2022 #1

要控制(以及所有“堆栈”),参数必须匹配:dtypeconcatenate

In [274]: np.vstack([np.array([1,2,3], 'float16'), np.ones(3,'float16')])
Out[274]: 
array([[1., 2., 3.],
       [1., 1., 1.]], dtype=float16)

的默认 dtype 为 :onesfloat64

In [275]: np.vstack([np.array([1,2,3], 'float16'), np.ones(3)])
Out[275]: 
array([[1., 2., 3.],
       [1., 1., 1.]])

In [276]: _.dtype
Out[276]: dtype('float64')

但正如评论中所指出的,使用只是表面上的四舍五入。float16

In [278]: np.vstack([np.array([1.234235,2.9999,3], 'float16'), np.ones(3,'float16')])
Out[278]: 
array([[1.234, 3.   , 3.   ],
       [1.   , 1.   , 1.   ]], dtype=float16)

转置不会更改值或 dtype。