numpy格式转化成list后小数位发生变化

问题

在使用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)

参考

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Python中,有几种方法可以控制保留小数位数。 第一种方法是使用round()函数来进行四舍五入。round()函数可以指定保留的小数位数,如果不指定,默认保留到最近的整数。但需要注意的是,由于浮点数的精度问题,round()函数在某些情况下可能会产生一定的误差。例如,round(2.675, 2)的结果是2.67,而不是预期的2.68。这是因为大多数十进制分数无法精确表示为浮点数。 第二种方法是将浮点数转换为字符串,然后进行字符串截取。你可以使用split()函数将浮点数分割成整数部分和小数部分,然后截取你想要的小数位数。但需要注意的是,这种方法不进行四舍五入,而是直接截取指定位数的小数。例如,对于浮点数2.345566,你可以使用str(a).split('.')[0:2]来截取小数点后的两位,结果是2.34。 第三种方法是使用numpy库中的set_printoptions()函数来设置打印选项。你可以使用precision参数来指定保留的小数位数,使用suppress参数来控制是否使用科学计数法,使用formatter参数来强制格式化打印内容。例如,使用np.set_printoptions(precision=3, suppress=True)可以设置保留三位小数并禁用科学计数法,而使用np.set_printoptions(formatter={'float': '{: 0.3f}'.format})可以强制格式化打印内容并补全小数位。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Python保留指定位数的小数【5种方法】](https://blog.csdn.net/weixin_45913084/article/details/130472886)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncle_ll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值