python - 字符串格式不能正确处理四舍五入的 Numpy Float32?
问题描述
将格式字符串与 Numpy 32 float 和 Numpy.round() 一起使用时,我意外地遇到了这种奇怪的行为。重现:
score=0.7827188774
npf32_score_rounded=np.round(np.float32(0.7827188774),4)
score_rounded=np.round(score,4)
print(f" {npf32_score_rounded}")
print(f" {score_rounded}")
print(npf32_score_rounded)
print(score_rounded)
#0.7827000021934509 expect to get 0.7827
#0.7827
#0.7827 # without string format, it works as expected
#0.7827
这种行为是正常的还是应该修复?
Numpy 版本 == 1.20.2
Python 版本 == 3.8.0
解决方案
Python 的 f 字符串调用 objects__format__
函数。从numpy 的源代码中可以看出,对于浮点数,它float
之前会转换为 Python(64 位)。
由于存储在 32 位浮点数中的值实际上是0.782700002193450927734375
(参见IEE 754),因为 Python 的精度更高,float
所以这些小数位现在很重要。这就是现在打印这些小数位的原因。感谢@user2357112 支持 Monica指出这一点。
所以这是预期的结果。
import numpy as np
val = 0.7827188774
np_float_32 = np.round(np.float32(val), 4)
assert type(np_float_32) == np.float32
np_float_64 = np.round(val, 4)
assert type(np_float_64) == np.float64
# just calling print, no issues
print(np_float_32, np_float_64) # 0.7827 0.7827
# both str and repr work as intended
print(str(np_float_32), str(np_float_64)) # 0.7827 0.7827
print(repr(np_float_32), repr(np_float_64)) # 0.7827 0.7827
# behavior described by OP
print(f'{np_float_32} {np_float_64}') # 0.7827000021934509 0.7827
# f-string without format specification calls obj.__format__('')
# see https://github.com/numpy/numpy/blob/v1.20.2/numpy/core/src/multiarray/scalartypes.c.src#L273
# explicit conversion to python float
print(float(np_float_32), float(np_float_64)) # 0.7827000021934509 0.7827
推荐阅读
- java - 映射中键的类型不匹配:预期 org.apache.hadoop.io.IntWritable,收到 org.apache.hadoop.io.LongWritable
- tensorflow - Tensorflow:了解带和不带 Dropout Wrapper 的 LSTM 输出
- android - 在图像上粘贴文本
- android - 应用程序运行时自动崩溃
- phpmyadmin - 用户'pma'@'localhost'的xampp访问被拒绝(使用密码:否)
- mysql - 将 .frm、.MYD、.MYI 文件复制到另一台计算机
- magento - Magento 2:重新启用缓存后的 ERR_TOO_MANY_REDIRECTS
- pega - 我在报告定义中遇到异常,我的属性映射到外部 mysql 数据库中,
- iis - 负载均衡器到 IIS 超时
- azure - 每个国家/地区架构的数据库