numpy中dtype转换的陷阱与正确用法:直接修改与astype的区别
本文深入解析NumPy中数据类型转换的两种机制:直接修改dtype属性与使用astype()方法。通过实验发现,直接修改dtype仅改变解释方式而不复制数据,导致数组长度随字节数变化而翻倍;而astype()则进行真正的数据转换并生成新数组,保持长度不变。文章提供了从文本文件读取数据时的最佳实践,建议始终使用astype()进行整数转换以避免意外错误。
本文探讨NumPy库中数值数据类型转换的具体实现与潜在陷阱。
导入numpy
>>> import numpy as np
一、随意探索数据类型行为
首先创建一个包含4个随机浮点数的数组。
>>> a = np.random.random(4)
查看该数组的基本信息,包括数据类型、形状和具体数值。
>>> a
array([ 0.0945377 , 0.52199916, 0.62490646, 0.21260126])
>>> a.dtype
dtype('float64')
>>> a.shape
(4,)
尝试将dtype直接修改为float32,观察发现数组长度意外翻倍。
>>> a.dtype = 'float32'
>>> a
array([ 3.65532693e+20, 1.43907535e+00, -3.31994873e-25,
1.75549972e+00, -2.75686653e+14, 1.78122652e+00,
-1.03207532e-19, 1.58760118e+00], dtype=float32)
>>> a.shape
(8,)
继续将dtype修改为float16,数组长度再次翻倍,变为原来的四倍。
>>> a.dtype = 'float16'
>>> a
array([ -9.58442688e-05, 7.19000000e+02, 2.38159180e-01,
1.92968750e+00, nan, -1.66034698e-03,
-2.63427734e-01, 1.96875000e+00, -1.07519531e+00,
-1.19625000e+02, nan, 1.97167969e+00,
-1.60156250e-01, -7.76290894e-03, 4.07226562e-01,
1.94824219e+00], dtype=float16)
>>> a.shape
(16,)
当将dtype改回float(即float64)时,数组长度恢复至最初的4个元素,且默认数据类型确认为float64。
>>> a.dtype = 'float'
>>> a
array([ 0.0945377 , 0.52199916, 0.62490646, 0.21260126])
>>> a.shape
(4,)
>>> a.dtype
dtype('float64')
将数组a的数据类型转换为整数类型,并观察其内部信息变化。
>>> a.dtype = 'int64'
>>> a
array([4591476579734816328, 4602876970018897584, 4603803876586077261,
4596827787908854048], dtype=int64)
>>> a.shape
(4,)
将dtype修改为int32,发现数组长度翻倍,元素数量变为8个。
>>> a.dtype = 'int32'
>>> a
array([ 1637779016, 1069036447, -1764917584, 1071690807, -679822259,
1071906619, -1611419360, 1070282372])
>>> a.shape
(8,)
继续将dtype修改为int16,数组长度再次翻倍,达到16个元素。
>>> a.dtype = 'int16'
>>> a
array([-31160, 24990, 13215, 16312, 32432, -26931, -19401, 16352,
-17331, -10374, -197, 16355, -20192, -24589, 13956, 16331], dtype=int16)
>>> a.shape
(16,)
进一步将dtype修改为int8,数组长度继续翻倍,最终拥有32个元素。
>>> a.dtype = 'int8'
>>> a
array([ 72, -122, -98, 97, -97, 51, -72, 63, -80, 126, -51,
-106, 55, -76, -32, 63, 77, -68, 122, -41, 59, -1,
-29, 63, 32, -79, -13, -97, -124, 54, -53, 63], dtype=int8)
>>> a.shape
(32,)
最后将dtype设置为int,系统默认将其解析为int32,此时数组长度为8。
>>> a.dtype = 'int'
>>> a.dtype
dtype('int32')
>>> a
array([ 1637779016, 1069036447, -1764917584, 1071690807, -679822259,
1071906619, -1611419360, 1070282372])
>>> a.shape
(8,)
二、另一种常见的数据处理场景
在从文本文件读取数据并转换为NumPy数组时,默认的数据类型通常是float64。然而,在某些应用场景下,我们需要将特定数据列视为整数。如果直接修改dtype为'int',会导致上述提到的数组长度翻倍问题,从而引发错误。
假设我们已经导入了数据,本意是希望这些数据列为整数类型,但实际获取的是float64类型的浮点数。
>>> b = np.array([1., 2., 3., 4.])
>>> b.dtype
dtype('float64')
使用astype(int)方法可以将数据转换为整数,同时保持数组长度不变,这是推荐的做法。
>>> c = b.astype(int)
>>> c
array([1, 2, 3, 4])
>>> c.shape
(8,)
>>> c.dtype
dtype('int32')
如果直接修改b的dtype属性,b的长度会翻倍,这通常不是我们期望的结果(除非你特意需要这种视图操作)。
>>> b
array([ 1., 2., 3., 4.])
>>> b.dtype = 'int'
>>> b.dtype
dtype('int32')
>>> b
array([ 0, 1072693248, 0, 1073741824, 0,
1074266112, 0, 1074790400])
>>> b.shape
(8,)
三、结论
在NumPy中,不能直接通过修改原数据的dtype属性来进行真正的数据类型转换。正确的做法是使用astype()函数,它会根据需要转换数据并生成一个新的数组对象。
到此这篇关于numpy数据类型dtype转换实现的文章就介绍到这了,更多相关numpy dtype转换内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









