2.NumPy基础
2.1 NumPy 数组对象
2.2 NumPy 数据类型
2.3 数据类型对象 (dtype)
2.4 创建自定义数据类型
NumPy提供的最重要的数据结构是一个称为NumPy数组(ndarray)的强大对象,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引,是Numpy中的底层数据类型。
ndarray 对象是用于存放同类型元素的多维数组。
ndarray 中的每个元素在内存中都有相同大小的区域。
ndarray 内部由以下内容组成:
ndarray 的内部结构:
跨度可以是负数,这样会使数组在内存中后向移动,切片中 obj[::-1] 或 obj[:,::-1] 就是如此。
创建一个 ndarray 只需调用 NumPy 的 array 函数即可:
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数说明:
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
快速创建一个向量(即一维的NumPy数组):
import numpy as np
my_array = np.array([1, 2, 3, 4, 5])
print(my_array)
OUT:
[1 2 3 4 5]
指定数据 dtype
int 64
a = np.array([1, 2, 3, 4, 5],dtype=np.int64)
print(a.dtype)
int64
float32
a = np.array([1, 2, 3, 4, 5],dtype=np.float32)
print(a.dtype)
[1. 2. 3. 4. 5.]
确定一下这个向量的维度
print(my_array.shape)
会输出:(5, )
,这表明这是一个包含5个元素的向量。数组的shape属性 返回一个元组(tuple),元组中的元素即为NumPy数组每一个维度上的大小。上面例子中的数组 是一维的,因此元组中只有一个元素
打印修改元素。NumPy数组的起始索引编号为0。
print my_array[0]
print my_array[1]
上述命令将分别在终端上打印1和2。还可以修改NumPy数组的元素。例如,假设我们编写以下2个命令:
my_array[0] = -1
print my_array
将在屏幕上看到:[-1,2,3,4,5]
。
Python支持的数据类型有整型、浮点型以及复数型,但这些类型不足以满足科学计算的需 求,而NumPy支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。在实际应用中,我们需要不同精度的数据类型, 它们占用的内存空间也是不同的。在NumPy中,大部分数据类型名是以数字结尾的,这个数字 表示其在内存中占用的位数。
下表列举了常用 NumPy 基本类型。
名称 | 描述 |
---|---|
bool_ | 用一位存储的布尔型数据类型(值为True 或者 False) |
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
int8 | 整数(-128 to 127) |
int16 | 整数(-32768 to 32767) |
int32 | 整数(-2147483648 to 2147483647,$-2^{31}至2^{31}-1$) |
int64 | 整数(-9223372036854775808 to 9223372036854775807,$-2^{63}至2^{63}-1$) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295,$0至2^{32}-1$) |
uint64 | 无符号整数(0 to 18446744073709551615,$0至2^{64}-1$) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数(16位),包括:1 个符号位(正负号),5 个指数位,10 个尾数位 |
float32 | 单精度浮点数(32位),包括:1 个符号位(正负号),8 个指数位,23 个尾数位 |
float64 | 双精度浮点数(64位),包括:1 个符号位(正负号),11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
numpy 的数值类型实际上是 dtype 对象的实例,并对应唯一的字符,包括 np.bool_,np.int32,np.float32,等等。
每一种数据类型均有对应的类型转换函数:
In: float64(42)
Out: 42.0
In: int8(42.0)
Out: 42
In: bool(42)
Out: True
In: bool(0)
Out: False
In: bool(42.0)
Out: True
In: float(True)
Out: 1.0
In: float(False)
Out: 0.0
每个numpy数组都是相同类型元素的网格。Numpy提供了一组可用于构造数组的大量数值数据类型。Numpy在创建数组时尝试猜测数据类型,但构造数组的函数通常还包含一个可选参数来显式指定数据类型。
x = np.array([1, 2]) # Let numpy choose the datatype
print(x.dtype) # Prints "int32"
x = np.array([1.0, 2.0]) # Let numpy choose the datatype
print(x.dtype) # Prints "float64"
在NumPy中,许多都函数的参数中可以指定数据类型,通常这个参数是可选的:
In: arange(7, dtype=uint16)
Out: array([0, 1, 2, 3, 4, 5, 6], dtype=uint16)
需要注意的是,复数是不能转换为整数的,这将触发TypeError错误,同样,复数也不能转换为浮点数。不过,浮点数却可以转换为复数,例如complex(1.0)。注意, 有$j$的部分为复数的虚部。
In: complex(1.0)
Out: (1+0j)
数据类型对象是numpy.dtype类的实例。如前所述,NumPy数组是有数据类型的,更确切地说,NumPy数组中的每一个元素均为相同的数据类型。
数据类型对象(numpy.dtype 类的实例)用来描述与数组对应的内存区域是如何使用,它描述了数据的以下几个方面:
数据的类型(整数,浮点数或者 Python 对象)
数据的大小(例如, 整数使用多少个字节存储)
dtype类的itemsize属性可以给出单个数组元素在 内存中占用的字节数。
x = np.array(2)
print(x.dtype) # print"int32"
print(x.dtype.itemsize) # print"4"
数据的字节顺序(小端法或大端法)
在结构化类型的情况下,字段的名称、每个字段的数据类型和每个字段所取的内存块的部分
如果数据类型是子数组,那么它的形状和数据类型是什么。
字节顺序是通过对数据类型预先设定 < 或 > 来决定的。 < 意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。> 意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。
dtype 对象是使用以下语法构造的:
numpy.dtype(object, align, copy)
自定义数据类型是一种异构数据类型,可以当做用来记录电子表格或数据库中一行数据的结 构。
示例:创建一个存储商店库存信息的数据类型。其中,用一个长度为40个字 符的字符串来记录商品名称,用一个32位的整数来记录商品的库存数量,最后用一个32位的单精度浮点数来记录商品价格。
(1) 创建数据类型:
In: t = np.dtype([('name', np.str_, 40), ('numitems', np.int32)('price',np.float32)])
In: t
Out: dtype([('name', '<U40'), ('numitems', '<i4'), ('price', '<f4')])
在用array函数创建数组时,如果没有在参数中指定数据类型,将默认为浮点数类型。而现在,想要创建自定义数据类型的数组,就必须在参数中指定数据类型,否则将触发TypeError错误:
In: t = np.dtype([('name', np.str_, 40), ('numitems', np.int32), ('price',np.float32)])
fruits = np.array([('banana', 423, 5.80), ('apple', 520, 2.72)], dtype=t)
fruits
Out: array([('banana', 423, 5.8 ), ('apple', 520, 2.72)],
dtype=[('name', '<U40'), ('numitems', '<i4'), ('price', '<f4')])
总结:我们可以自定义一种异构数据类型,该类型包括一个用字符串记录的名字、一个用整数记录的数字以及一个用浮点数记录的价格。