2. NumPy数据类型

本章就NumPy的一些基础知识展开,首先讨论的是NumPy的数据类型问题。

2.1 NumPy支持的数据类型

尽管Python支持int、float等基础的数据类型,但是NumPy需要更多、更精确的数据类型支持科学计算以及内存分配的需要。以下是NumPy里支持的数值型数据的类型。

表1 NumPy支持的数值类型

符号 含义
bool True和Flase
inti 支持int的32或64位
int8 8位的整形(-128~127)
int16 -32768~32767
int32 -2 ** 31 ~ 2 ** 31 - 1
int64 -2 ** 63 ~ 2 ** 63 - 1
uint8 8位的整形(0~255)
uint16 -32768~32767
uint32 0 ~ 2 ** 32 - 1
uint64 0 ~ 2 ** 64 - 1
float16 1位符号位,5位指数位,10位
float32 1位符号位,8位指数位,23位
float64、float 1位符号位,11位指数位,52位

另一种描述数据的类型的方式是用一个字符来描述使用的NumPy的数值数据的类型,例如'i'字符代表有符号整形数据,'f'代表浮点型数据,其余字符代表的数值数据的类型如下表格所示:

表2 NumPy的数值类型

符号 含义
b boolean
i signed integer
u unsigned integer
f floating-point
c complex floating-point
m timedelta
M datetime
O object
S (byte-)string
U Unicode
V void

表1和表2仅仅是列出了较为常用的NumPy支持的数据类型,可以通过sctypeDict.keys()查看NumPy里支持的所有数据类型。

# IDLE里执行或Python的Shell里
>>> sctypeDict.keys() 

对于每种类型都有同名的转换函数可以将数据转为某种数据类型的数据。

from numpy import *
# 34.5转为8位整形,即1字节
print int8(34.5)
# 34.5转为布尔值即True或Flase
print bool(34.5)

而许多的NumPy下的函数有可选的参数dtype可以指定数据的类型,类型值。

from numpy import *
print arange(10, dtype=uint8)
y = arange(7, dtype = 'u2')
print y.itemsize
print y.dtype

程序执行结果如下所示:

[0 1 2 3 4 5 6 7 8 9]
2
uint16

2.2 dtype函数创建"新"类型

上一节介绍的是NumPy支持的数据类型,在NumPy里属于元(原子性、不可分、最小单位)数据类型,可以将这些类型组合一下成为更为复杂的类型,类似于C语言里的结构体的概念。

NumPy下可以用dtype函数创建一个自己的类型(有些类似于表格的一条记录的各个字段类型)。用自定义的数据类型可以在numpy存储类似于表格的数据,示例如下所示:

姓名 年龄 数学
李明 44 98
杨幂 32 58

可以设计一个新的类型有三个字段"name"、“age”、“math”来分别记录姓名、年龄和数学成绩。需指定每个字段名和字段的类型,字段名和字段类型可以以元组或列表的形式成对给出,如果“表”有多个字段那么作为dtype形参列表(元组)里的各项。

from numpy import *
#创建一个数据类型 t
t = dtype([("name", str_, 40), ("age", uint8), ("math", uint8)])
# 创建数组x,数组元素类型为 t
x = array([("liming", 35, 78),("yangmi", 31, 58)], dtype = t)
print x
print x[0]["name"]
print x[1]["math"]

新建的类型可以作为函数的dtype的值。程序执行结果如下:

[('liming', 35, 78) ('yangmi', 31, 58)]
liming
58

可以用'S'来定义字符串类型,"u8"定义uint8类型数据。

from numpy import *
t = dtype([("name", "S40"), ("age", "u8"), ("math", "f")])
y = array([("liming", 44, 98),("yangmi", 32, 58)], dtype = t)
print y[1]["age"]
print y["age"]
print y[0]

程序执行结果如下:

[('name', '|S40'), ('age', '|u1'), ('math', '|u1')]
32
[44,32]
["liming", 44, 98]

从结果可以看出,对于这种复合的类型可以按行(记录)访问print y[0],也可以按列(字段)访问print y["age"]