Numpy - ndarray的dtype
1.数据类型
NumPy 支持比 Python 更多种类的数值类型。 下表显示了 NumPy 中定义的不同标量数据类型。
数据类型 | 说明 |
---|---|
bool | 布尔类型,True或者False。 |
intc | 与C语言的int类型一致,一般是int32或者int64 |
intp | 用于索引的整数,与C预言中的ssize_t一致,int32或者int64 |
int8 | 字节长度的整数,取值:[-128, 127] |
int16 | 16位长度的整数,取值:[-32768, 32767] |
int32 | 32位长度的整数,取值:[-231, 231-1] |
int64 | 64位长度的整数,取值:[-263, 263-1] |
uint8 | 8位无符号整数,取值:[0, 255] |
uint16 | 16位无符号整数,取值:[0, 65535] |
uint32 | 32位无符号整数,取值:[0, 232-1] |
uint64 | 64位无符号整数,取值:[0, 264-1] |
float16 | 16位半精度浮点数:1位符号位,5位指数,10位尾数 |
float32 | 32位半精度浮点数:1位符号位,8位指数,23位尾数 |
float64 | 64位半精度浮点数:1位符号位,11位指数,52位尾数 |
complex64 | 复数类型,实部和虚部都是32位浮点数 |
complex128 | 复数类型,实部和虚部都是64位浮点数 |
浮点数:(符号)尾数*10指数;
复数:实部(.real)+虚部i(.imag);
NumPy 数字类型是dtype
(数据类型)对象的实例,每个对象具有唯一的特征。 这些类型可以是np.bool_
,np.float32
等。
每个内建类型都有一个唯一定义它的字符代码(后续在定义dtype的时候会用到):
'b'
:布尔值'i'
:符号整数'u'
:无符号整数'f'
:浮点'c'
:复数浮点'm'
:时间间隔'M'
:日期时间'O'
:Python 对象'S', 'a'
:字节串'U'
:Unicode'V'
:原始数据(void
)
2.数据类型对象 (dtype
)
数据类型对象描述了对应于数组的固定内存块的解释,取决于以下方面:
数据类型(整数、浮点或者 Python 对象)
数据大小
字节序(小端或大端)
在结构化类型的情况下,字段的名称,每个字段的数据类型,和每个字段占用的内存块部分。
如果数据类型是子序列,它的形状和数据类型。
字节顺序取决于数据类型的前缀<
或>
。<
意味着编码是小端(最小有效字节存储在最小地址中)。>
意味着编码是大端(最大有效字节存储在最小地址中)。
dtype
可由一下语法构造:
numpy.dtype(object, align, copy)
参数为:
Object
:被转换为数据类型的对象。Align
:如果为true
,则向字段添加间隔,使其类似 C 的结构体。Copy
? 生成dtype
对象的新副本,如果为flase
,结果是内建数据类型对象的引用。
示例 1
#使用数组标量类型
import numpy as np
dt = np.dtype(np.int32)
print(dt)
输出如下:
int32
示例 2
#int8,int16,int32,int64 可替换为等价的字符串 'i1','i2','i4',以及其他。
import numpy as np
dt = np.dtype('i4')
print(dt)
输出如下:
int32
示例 3
#使用端记号
import numpy as np
dt = np.dtype('>i4')
print(dt)
输出如下:
>i4
下面的例子展示了结构化数据类型的使用。 这里声明了字段名称和相应的标量数据类型。
示例 4
#首先创建结构化数据类型。
import numpy as np
#该定义声明一个数据类型,该类型的名称为age,age对应的类型是np.int8,也可以理解成新的数据类型是一个元组
#使用numpy的这种定义方式可以创建出更加复杂的结构
dt = np.dtype([('age',np.int8)])
print(dt)
输出如下:
[('age', 'i1')]
示例 5
#现在将其应用于 ndarray 对象
import numpy as np
dt = np.dtype([('age',np.int8)])
a = np.array([(10,i1),(20,),(30,)], dtype = dt)
print(a)
print(a.dtype)
输出如下:
[(10,) (20,) (30,)]
[('age', 'i1')]
示例 6
#名称可用于访问 age 列的内容
import numpy as np
dt = np.dtype([('age',np.int8)])
a = np.array([(10,),(20,),(30,)], dtype = dt)
print(a['age'])
输出如下:
[10 20 30]
示例 7
以下示例定义名为student的结构化数据类型,其中包含字符串字段name
,整数字段age
和浮点字段marks
。 此dtype
应用于ndarray
对象。
#定义名为student的结构化数据类型,其中包含字符串字段name,整数字段age和浮点字段marks
import numpy as np
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
print(student)
输出如下:
[('name', 'S20'), ('age', 'i1'), ('marks', '<f4')])
示例 8
import numpy as np
student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')])
a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student)
print(a)
输出如下:
[('abc', 21, 50.0), ('xyz', 18, 75.0)]
3.通过赋值dtype=?,数组长度发生变化
实验1:生成一个浮点数组
a = np.random.random(4)
print(a)
print(a.dtype)
print(a.shape)
输出如下:
[ 0.76903944 0.7028335 0.39706829 0.26833247]
float64
(4,)
实验2:改变dtype,发现数组长度翻倍!
print(a)
print(a.dtype)
print(a.shape)
输出如下:
[ -5.87888240e-23 1.81725979e+00 -3.26580278e-12 1.80070829e+00
3.69795589e-23 1.69853413e+00 -1.25154113e+33 1.63416612e+00]
float32
(8,)
实验3:改变dtype,数组长度再次翻倍!
a.dtype = 'float16'
print(a)
print(a.dtype)
print(a.shape)
输出如下:
[ 1.76544189e-02 -3.20053101e-03 -3.89099121e-03 1.97656250e+00
-2.98906250e+01 -6.86645508e-02 nan 1.97460938e+00
-5.18125000e+01 3.02505493e-03 2.85000000e+03 1.96191406e+00
-5.34375000e+01 -2.64640000e+04 6.80541992e-02 1.95410156e+00]
float16
(16,)
实验4:改变dtype='float',发现默认就是float64,长度也变回最初的4
a.dtype = 'float'
print(a)
print(a.dtype)
print(a.shape)
输出如下:
[ 0.76903944 0.7028335 0.39706829 0.26833247]
float64
(4,)
实验5:把a变为整数,观察其信息
a.dtype = 'int64'
print(a)
print(a.dtype)
print(a.shape)
输出如下:
[4605102111033533573 4604505780893634425 4600824566266385018 4598505468010615470]
int64
(4,)
实验6:改变dtype,发现数组长度翻倍!
a.dtype = 'int32'
print(a)
print(a.dtype)
print(a.shape)
输出如下:
[-1701960571 1072208888 -1402613895 1072070044 439538298 1071212945 -159984978 1070672987]
int32
(8,)
4.用 astype(int) 改变数据类型,不改变数组长度
很多时候我们从文本文件读取数据变成numpy的数组,默认的dtype是float64。
但是有些场合我们希望有些数据列作为整数。如果直接改dtype='int'的话,就会出错!原因如上,数组长度翻倍了!!!
下面的场景假设我们得到了浮点型的数据。我们的本意是希望它们是整数,但实际上是却是浮点数(float64)
b= np.array([1., 2., 3., 4.])
b.dtype
输出如下:
dtype('float64')
实验一:用 astype(int) 得到整数,并且不改变数组长度
b.astype(np.int32)
print(b)
print(b.dtype)
print(b.shape)
输出如下:
[ 1. 2. 3. 4.]
float64
(4,)
实验一:直接改变b的dtype的话,数组长度翻倍
b= np.array([1., 2., 3., 4.])
b.dtype='int32'
print(b)
print(b.dtype)
print(b.shape)
输出如下:
[ 0 1072693248 0 1073741824 0 1074266112
0 1074790400]
int32
(8,)
三、结论
numpy中的数据类型转换,不能直接改原数据的dtype! 只能用函数astype()。