您的位置:首页 > 编程语言 > Python开发

彻底剖析numpy的数据类型

2017-11-22 23:21 267 查看

彻底剖析numpy的数据类型

1.类型及其转换

numpy中,array的许多生成函数默认使用的是float64数据类型:

>>> a = np.ones((3, 3))
>>> a.dtype
dtype('float64')


但是,对于传入参数为list的构造方式,则会视情况而进行自动类型确认:

>>> a = np.array([1, 2, 3])
>>> a.dtype
dtype('int32')
>>> a = np.array([1., 2., 3.])
>>> a.dtype
dtype('float64')


生成后的array还会根据需要自动进行向上类型转换:

>>> a = np.array([1, 2, 3])
>>> a = a + 1.5
>>> a.dtype
dtype('float64')


但是,赋值操作却不会引起array的类型发生变化:

>>> a = np.array([1, 2, 3])
>>> a.dtype
dtype('int64')
>>> a[0] = 1.9     # <-- 浮点数1.9会被强制转换为int64类型
>>> a
array([1, 2, 3])


强制类型转换操作:

>>> a = np.array([1.7, 1.2, 1.6])
>>> b = a.astype(int)   # <-- 强制类型转换
>>> b.dtype
dtype('int32')


四舍五入取整:

>>> a = np.array([1.2, 1.5, 1.6, 2.5, 3.5, 4.5])
>>> b = np.around(a)
>>> b.dtype     # 取整后得到的array仍然是浮点类型
dtype('float64')
>>> c = np.around(a).astype(int)
>>> c.dtype
dtype('int32')


2.每种数据类型的实际大小

2.1.整型(有符号):

数据类型实际大小
int88bit
int1616bit
int3232bit
int6464bit
>>> np.array([1], dtype=int).dtype
dtype('int64')
>>> np.iinfo(np.int32).max, 2**31 - 1
(2147483647, 2147483647)


2.2.整型(无符号):

数据类型实际大小
uint88bit
uint1616bit
uint3232bit
uint6464bit
>>> np.iinfo(np.uint32).max, 2**32 - 1
(4294967295, 4294967295)


2.3.浮点数:

数据类型实际大小
float1616bit
float3232bit
float6464bit
float9696bit
float128128bit
>>> np.finfo(np.float32).eps
1.1920929e-07
>>> np.finfo(np.float64).eps
2.2204460492503131e-16

>>> np.float32(1e-8) + np.float32(1) == 1
True
>>> np.float64(1e-8) + np.float64(1) == 1
False


2.4.浮点复数:

数据类型实际大小
complex642个32bit浮点数
complex1282个64bit浮点数
complex1922个96bit浮点数
complex2562个128bit浮点数

3.自定义结构体

所谓自定义结构体,有点像C/C++里面的struct,下面演示一个这样的自定义结构体,它有3个数据元素:

元素名称数据类型
sensor_code长度为4的字符串
positionfloat
valuefloat
>>> samples = np.zeros((6,), dtype=[('sensor_code', 'S4'),
...                                 ('position', float), ('value', float)])
>>> samples.ndim
1
>>> samples.shape
(6,)
>>> samples.dtype.names
('sensor_code', 'position', 'value')

>>> samples[:] = [('ALFA',   1, 0.37), ('BETA', 1, 0.11), ('TAU', 1,   0.13),
...               ('ALFA', 1.5, 0.37), ('ALFA', 3, 0.11), ('TAU', 1.2, 0.13)]
>>> samples
array([('ALFA', 1.0, 0.37), ('BETA', 1.0, 0.11), ('TAU', 1.0, 0.13),
('ALFA', 1.5, 0.37), ('ALFA', 3.0, 0.11), ('TAU', 1.2, 0.13)],
dtype=[('sensor_code', 'S4'), ('position', '<f8'), ('value', '<f8')])


使用索引下标:

>>> samples['sensor_code']
array(['ALFA', 'BETA', 'TAU', 'ALFA', 'ALFA', 'TAU'],
dtype='|S4')
>>> samples['value']
array([ 0.37,  0.11,  0.13,  0.37,  0.11,  0.13])
>>> samples[0]
('ALFA', 1.0, 0.37)

>>> samples[0]['sensor_code'] = 'TAU'
>>> samples[0]
('TAU', 1.0, 0.37)


一次性取出两列数据:

>>> samples[['position', 'value']]
array([(1.0, 0.37), (1.0, 0.11), (1.0, 0.13), (1.5, 0.37), (3.0, 0.11),
(1.2, 0.13)],
dtype=[('position', '<f8'), ('value', '<f8')])


还可以进行条件筛选操作:

samples[samples['sensor_code'] == 'ALFA']
array([('ALFA', 1.5, 0.37), ('ALFA', 3.0, 0.11)],
dtype=[('sensor_code', 'S4'), ('position', '<f8'), ('value', '<f8')])


4.使用maskedarray处理缺失/非法值

在构造array时,传进去一个mask参数,可以标识某部分数据为缺失/非法值

>>> x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1])
>>> x
masked_array(data = [1 -- 3 --],
mask = [False  True False  True],
fill_value = 999999)

>>> y = np.ma.array([1, 2, 3, 4], mask=[0, 1, 1, 1])
>>> x + y
masked_array(data = [2 -- -- --],
mask = [False  True  True  True],
fill_value = 999999)


一般来说,mask类型数据常常产生于一些数学运算:

>>> np.ma.sqrt([1, -1, 2, -2])
masked_array(data = [1.0 -- 1.41421356237... --],
mask = [False  True False  True],
fill_value = 1e+20)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息