
在使用numpy进行数值计算时,数据类型(`dtype`)的选择至关重要。不当的数据类型,特别是使用如`np.uint8`等固定位宽的整数类型时,如果数据值超出其表示范围,将导致整数溢出,从而产生非预期的数据更改。本文将深入探讨numpy数据类型溢出的机制,并通过实例展示如何识别并避免此类问题,确保数据处理的准确性。
NumPy数组是Python中进行高效数值计算的核心工具,其性能优势部分来源于对底层数据类型的严格管理。每个NumPy数组都有一个dtype属性,它定义了数组中每个元素的数据类型,例如np.int32(32位有符号整数)、np.float64(64位浮点数)或np.uint8(8位无符号整数)。
当一个数值被存储到一个无法完全表示它的数据类型中时,就会发生数据溢出。对于整数类型,这意味着如果一个值超出了该类型所能表示的最大值,它会“回绕”到最小值,或者被截断。以np.uint8为例,它是一个8位无符号整数,其可表示的范围是0到255。任何小于0或大于255的整数在被强制转换为np.uint8时,都会发生溢出。例如,573转换为np.uint8时,会因为溢出而变为61(573 % 256 = 61)。
考虑一个场景,我们需要对一组二维坐标点进行重新排序。初始数据可能包含较大的坐标值,例如:
import numpy as np
input_data = np.array([[[ 573, 148]],
[[ 25, 223]],
[[ 153, 1023]],
[[ 730, 863]]])
print(f"原始数据类型: {input_data.dtype}")
print(f"原始数据:\n{input_data}")输出显示input_data的dtype通常会默认为np.int32或np.int64,这足以存储这些较大的值。
现在,假设我们编写了一个函数来处理这些点,但在初始化输出数组时错误地指定了np.uint8数据类型:
def reorder_with_overflow(points):
points = points.reshape((4, 2))
# 错误地指定了np.uint8数据类型
points_new = np.zeros((4, 1, 2), np.uint8)
add = points.sum(1)
diff = np.diff(points, axis=1)
points_new[0] = points[np.argmin(add)]
points_new[3] = points[np.argmax(add)]
points_new[1] = points[np.argmin(diff)]
points_new[2] = points[np.argmax(diff)]
return points_new
output_data_overflow = reorder_with_overflow(input_data)
print(f"\n使用np.uint8后的输出数据类型: {output_data_overflow.dtype}")
print(f"使用np.uint8后的输出数据:\n{output_data_overflow}")观察上述代码的输出,你会发现output_data_overflow中的许多值与input_data中的原始值不符。例如,573变成了61,1023变成了255,730变成了218。这就是典型的整数溢出现象。
为了进一步验证,我们可以直接将原始数据强制转换为np.uint8来观察其效果:
print(f"\n将原始数据强制转换为np.uint8:\n{input_data.astype(np.uint8)}")输出结果会与output_data_overflow中的“错误”值完全一致,这明确地指出了问题根源。
易通cmseasy免费的企业建站程序2.0 UTF-8 build 201000510 中文版
易通(企业网站管理系统)是一款小巧,高效,人性化的企业建站程序.易通企业网站程序是国内首款免费提供模板的企业网站系统.§ 简约的界面及小巧的体积:后台菜单完全可以修改成自己最需要最高效的形式;大部分操作都集中在下拉列表框中,以节省更多版面来显示更有价值的数据;数据的显示以J*ascript数组类型来输出,减少数据的传输量,加快传输速度。 § 灵活的模板标签及模
0
查看详情
解决这个问题的关键是确保所有参与计算和存储的NumPy数组都使用能够容纳其数据范围的数据类型。对于本例中的坐标值,如果它们可能超过255,则应选择更大的整数类型,例如np.int16、np.int32或np.int64。
以下是修正后的reorder函数:
def reorder_corrected(points):
points = points.reshape((4, 2))
# 修正:使用与输入数据兼容的数据类型,或根据数据范围选择更大的类型
# 这里的dtype可以从points数组继承,或者明确指定如np.int32
points_new = np.zeros((4, 1, 2), dtype=points.dtype)
add = points.sum(1)
diff = points.diff(points, axis=1)
points_new[0] = points[np.argmin(add)]
points_new[3] = points[np.argmax(add)]
points_new[1] = points[np.argmin(diff)]
points_new[2] = points[np.argmax(diff)]
return points_new
output_data_corrected = reorder_corrected(input_data)
print(f"\n修正后的输出数据类型: {output_data_corrected.dtype}")
print(f"修正后的输出数据:\n{output_data_corrected}")现在,output_d
ata_corrected将包含与原始input_data中相同的值,只是按照逻辑进行了重新排序,而没有发生数据丢失或改变。
在原始问题中,用户提到了一个使用Python列表实现的版本,该版本没有出现数据溢出。这是因为Python的内置列表可以存储任意Python对象(包括NumPy数组元素),它们本身不强制固定位宽的数据类型。当最终通过np.array(lst)将列表转换为NumPy数组时,NumPy会根据列表中的数据自动推断一个合适的数据类型(通常是np.int32或np.int64),这个类型足以容纳所有值,因此避免了溢出。
def reorder_by_lst(points):
points = points.reshape((4, 2))
add = points.sum(1)
diff = np.diff(points, axis=1)
a = points[np.argmin(add)]
d = points[np.argmax(add)]
b = points[np.argmin(diff)]
c = points[np.argmax(diff)]
lst = [a, b, c, d]
return np.array(lst) # NumPy会根据lst中的数据自动推断dtype
output_data_list_version = reorder_by_lst(input_data)
print(f"\n列表版本转换后的NumPy数组数据类型: {output_data_list_version.dtype}")
print(f"列表版本转换后的NumPy数组:\n{output_data_list_version}")这个例子进一步强调了NumPy在创建数组时自动推断dtype的机制,以及手动指定dtype时需要注意的潜在陷阱。
print(np.iinfo(np.uint8)) print(np.iinfo(np.int16))
这有助于选择合适的数据类型。
NumPy的数据类型管理是其强大功能的核心,但同时也带来了潜在的陷阱,特别是整数溢出。当数据值超出所选dtype的表示范围时,NumPy不会抛出错误,而是默默地进行“回绕”操作,导致数据看似被“更改”。通过理解dtype的作用、明确指定数据类型、并利用np.iinfo等工具检查类型范围,开发者可以有效避免这类问题,确保NumPy数值计算的准确性和可靠性。在编写NumPy代码时,始终对数据的预期范围和所选数据类型保持警惕,是构建健壮应用程序的关键。
以上就是Numpy数组数据类型溢出:避免意外数据更改的教程的详细内容,更多请关注其它相关文章!
相关文章:
j*a toString()的覆盖
将PCM16音频数据转换为W*并编码为Base64教程
CSS布局:解决全屏元素100%尺寸与外边距导致的页面溢出问题
迅雷下载到U盘速度很慢怎么办_迅雷U盘下载慢优化方法
如何在J*a中实现统一对象行为接口_项目大型化时的接口规范化
蛙漫正版漫画平台入口_蛙漫免费阅读全站漫画资源
TikTok国际版网页端快速入口 TikTok全球版短视频浏览教程
sublime如何配置Python开发环境_将sublime打造成轻量级Python IDE
PHP面向对象编程中避免重复创建PDO数据库连接的最佳实践
Typer应用中灵活处理命令行参数的令牌化与解析
解决Tabulator日期时间排序问题的专业指南
python3时间如何用calendar输出?
C++编译期如何执行复杂计算_C++模板元编程(TMP)技巧与应用
解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误
J*a应用程序首次运行自动创建文件与目录的最佳实践
Win11截图该按哪些键 Win11截屏完整流程解析【教程】
UC浏览器官网入口2025最新 UC浏览器网页版正式地址
漫蛙官网正版漫画入口 漫蛙2官方网页登录地址
J*aScript Promise链中如何正确终止后续.then执行并处理错误
移动端XML文件怎么转换成Excel 手机和平板上的解决方案
sublime如何配置Go语言开发环境_sublime搭建Golang编译运行系统
poki免费入口快捷访问 poki人气小游戏直接玩站点
163邮箱官方主页登录 直达网易邮箱登录核心页面
使用Python高效删除Word宏并转换DOCM为DOCX格式
百度网盘网页版入口 百度网盘网页版官方登录网址
Lar*el Eloquent:高效统计带条件关联模型的数量
蛙漫画网页版全站入口 蛙漫热门作品免费浏览
Vue.js 图片显示异常排查:理解应用挂载范围与DOM ID唯一性
Lar*el开发:如何在编辑界面正确预选数据库中的多选标签
腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程
Win11 USB传输速度慢怎么解决 Win11 USB驱动更新与设置
抖音从哪里进入网页版_抖音官方入口链接
TikTok搜索不到用户发布内容怎么办 TikTok用户内容搜索优化方法
Walmart退货API集成指南:PHP cURL实现与常见问题解析
抖音未来赚钱的新趋势 2025年值得关注的变现风口分析
漫蛙漫画网页端入口 漫蛙2官方正版漫画站点
2025俄罗斯Yandex最新入口 官方网站地址及浏览器下载指南
PHP表单提交消息延迟显示:Post-Redirect-Get模式深度解析与实践
UC浏览器如何安装插件 UC浏览器添加扩展程序详细教程【进阶】
Python中高效访问嵌套字典与列表中的键值对
AngularJS $http POST请求数据传递与Go后端接收实践
网易大神账号申诉需要多久_网易大神账号申诉流程说明
Pandas DataFrame 多条件优先级排序与排名
QQ官网正版登录链接 QQ在线登录入口最新
J*aScript对象创建方式_J*aScript设计模式应用
Promise错误处理:在catch后终止链式then执行的策略
c++如何实现一个简单的软件渲染器_c++从零开始的3D图形学
抖音网页版企业服务中心登录入口_抖音网页版企业登录平台
AO3最新入口2025公告_AO3中文官网合集
如何让 composer 信任自签名的 HTTPS 证书源?