问题
在使用numpy中,有一个需求是想将float32数据的小数截取一下,以减少所占内存,节省空间以及减少后续的计算时间。
numpy中有一些函数是可以定义精度的:
np.around()
: 四舍五入,可指定精度np.floor()
:向下取整数np.ceil()
:向上取整数
按照上述的需求,应该采用np.around()
np.around(a, decimals=0, out=None)
- a:是输入的numpy数组
- decimals是要保持的小数位数。默认值为0,如果为负,整数将四舍五入到小数点左侧的位置
在使用np.around()
函数之后,能够很好的完成上述需求,但是在转换成list格式保持成json文件就出现问题了:
import numpy as np
n = (np.random.random(10) * 30).astype(np.float32)
# array([29.973309, 8.078702, 11.52185, 17.46122, 18.514679, 19.36506, 28.817068, 0.83403945, 18.013485, 20.978584], dtype=float32)
# keep 2 decimals
n2 = np.around(n, 2)
print(n2) # array([29.97, 8.08, 11.52, 17.46, 18.51, 19.37, 28.82, 0.83, 18.01, 20.98], dtype=float32)
# convert into list
n2_list = n2.tolist()
print(n2_list) # [29.969999313354492, 8.079999923706055, 11.520000457763672, 17.459999084472656, 18.510000228881836, 19.3700008392334, 28.81999969482422, 0.8299999833106995, 18.010000228881836, 20.979999542236328]
可以看到,转成list之后小数点又不是想要保存的两位小数了,原因查了一下是,是格式的问题。
- numpy中浮点数一般是使用的np.float32
- python中浮点数一般是使用的float64,更精确一些,因此会出现上述问题
精度其实并没有被丢失,而是numpy的方式保存的精度要差一些,转化成list之后,float64有更为精确的表示。
解决办法
对转成list的数据再做一次精度设置
# keep 2 decimal
n2_list2 = [round(i, 2) for i in n2_list]
print(n2_list2) # [29.97, 8.08, 11.52, 17.46, 18.51, 19.37, 28.82, 0.83, 18.01, 20.98]
# keep into json file
import json
json.dumps(n2_list2)