NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
ndarray 对象是用于存放同类型元素的多维数组。
ndarray 中的每个元素在内存中都有相同存储大小的区域。
ndarray 内部由以下内容组成:
一个指向数据(内存或内存映射文件中的一块数据)的指针。
数据类型或 dtype,描述在数组中的固定大小值的格子。
一个表示数组形状(shape)的元组,表示各维度大小的元组。
一个跨度元组(stride),其中的整数指的是为了前进到当前维度下一个元素需要"跨过"的字节数。
numpy.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
1 import numpy as np 2 a = np.array([1,2,3]) 3 print (a) 4 [1 2 3] 5 # 多于一个维度 6 a = np.array([[1, 2], [3, 4]]) 7 print (a) 8 [[1 2] 9 [3 4]] 10 # 最小维度 11 a = np.array([1,2,3,4],ndmin = 3) 12 print(a) 13 [[[1 2 3 4]]] 14 # dtype 参数 15 a = np.array([1, 2, 3], dtype = float) 16 print (a) 17 [1. 2. 3.]
numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型。下表列举了常用 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) |
int64 | 整数(-9223372036854775808 to 9223372036854775807) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295) |
uint64 | 无符号整数(0 to 18446744073709551615) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
数据类型对象(numpy.dtype 类的实例)用来描述与数组对应的内存区域是如何使用,它描述了数据的以下几个方面::
字节顺序是通过对数据类型预先设定 < 或 > 来决定的。 < 意味着小端法(最小值存储在最小的地址,即低位组放在最前面)。> 意味着大端法(最重要的字节存储在最小的地址,即高位组放在最前面)。
dtype 对象是使用以下语法构造的:
numpy.dtype(object, align, copy)
1 # 使用标量类型 2 dt = np.dtype(np.int32) 3 print(dt) 4 int32 5 # int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替 6 dt = np.dtype('i4') 7 print(dt) 8 dtype('int8') 9 # 字节顺序标注 10 dt = np.dtype('<i4') 11 print(dt) 12 int32 13 # 首先创建结构化数据类型 14 dt = np.dtype([('age',np.int8)]) 15 print(dt) 16 [('age', 'i1')] 17 # 将数据类型应用于 ndarray 对象 18 dt = np.dtype([('age',np.int8)]) 19 a = np.array([(10,),(20,),(30,)], dtype = dt) 20 print(a) 21 [(10,) (20,) (30,)] 22 # 类型字段名可以用于存取实际的 age 列 23 dt = np.dtype([('age',np.int8)]) 24 a = np.array([(10,),(20,),(30,)], dtype = dt) 25 print(a['age']) 26 [10 20 30] 27 # 定义一个结构化数据类型 student,包含字符串字段 name,整数字段 age,及浮点字段 marks,并将这个 dtype 应用到 ndarray 对象 28 student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')]) 29 print(student) 30 [('name', 'S20'), ('age', 'i1'), ('marks', '<f4')] 31 student = np.dtype([('name','S20'), ('age', 'i1'), ('marks', 'f4')]) 32 a = np.array([('abc', 21, 50),('xyz', 18, 75)], dtype = student) 33 print(a) 34 print('姓名:',a['name']) 35 print('年龄:', a['age']) 36 print('成绩:',a['marks']) 37 [(b'abc', 21, 50.) (b'xyz', 18, 75.)] 38 姓名: [b'abc' b'xyz'] 39 年龄: [21 18] 40 成绩: [50. 75.]
NumPy 数组的维数称为秩(rank),秩就是轴的数量,即数组的维度,一维数组的秩为 1,二维数组的秩为 2,以此类推。
在 NumPy中,每一个线性的数组称为是一个轴(axis),也就是维度(dimensions)。比如说,二维数组相当于是两个一维数组,其中第一个一维数组中每个元素又是一个一维数组。所以一维数组就是 NumPy 中的轴(axis),第一个轴相当于是底层数组,第二个轴是底层数组里的数组。而轴的数量——秩,就是数组的维数。
属性 | 说明 |
---|---|
ndarray.ndim | 秩,即轴的数量或维度的数量 |
ndarray.shape | 数组的维度,对于矩阵,n 行 m 列 |
ndarray.size | 数组元素的总个数,相当于 .shape 中 n*m 的值 |
ndarray.dtype | ndarray 对象的元素类型 |
ndarray.itemsize | ndarray 对象中每个元素的大小,以字节为单位 |
ndarray.flags | ndarray 对象的内存信息 |
ndarray.real | ndarray元素的实部 |
ndarray.imag | ndarray 元素的虚部 |
ndarray.data | 包含实际数组元素的缓冲区,由于一般通过数组的索引获取元素,所以通常不需要使用这个属性。 |
1 # ndarray.ndim 用于返回数组的维数,等于秩 2 a = np.arange(24) 3 print(a) 4 print ('a维度:' , a.ndim) # a 现只有一个维度 5 # 现在调整其大小 6 b = a.reshape(2,2,6) # b 现在拥有三个维度 7 print(b) 8 print ('b维度:' , b.ndim) 9 [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23] 10 a维度: 1 11 [[[ 0 1 2 3 4 5] 12 [ 6 7 8 9 10 11]] 13 14 [[12 13 14 15 16 17] 15 [18 19 20 21 22 23]]] 16 b维度: 3 17 # ndarray.shape 表示数组的维度,返回一个元组,这个元组的长度就是维度的数目,即 ndim 属性(秩) 18 a = np.array([[1,2,3],[4,5,6]]) 19 print (a.shape) 20 b = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) 21 print(b.shape) 22 (2, 3) 23 (2, 2, 3) 24 # 调整数组大小 25 a = np.array([[1,2,3],[4,5,6]]) 26 a.shape = (3,2) 27 print (a) 28 a.shape = (1,6) 29 print (a) 30 [[1 2] 31 [3 4] 32 [5 6]] 33 [[1 2 3 4 5 6]] 34 # NumPy 也提供了 reshape 函数来调整数组大小 35 a = np.array([[1,2,3],[4,5,6]]) 36 b = a.reshape(3,2) 37 print (b) 38 [[1 2] 39 [3 4] 40 [5 6]] 41 # ndarray.itemsize 以字节的形式返回数组中每一个元素的大小 42 # 数组的 dtype 为 int8(一个字节) 43 x = np.array([1,2,3,4,5], dtype = np.int8) 44 print (x.itemsize) 45 46 # 数组的 dtype 现在为 float64(八个字节) 47 y = np.array([1,2,3,4,5], dtype = np.float64) 48 print (y.itemsize) 49 1 50 8 51 # ndarray.flags 返回 ndarray 对象的内存信息 52 x = np.array([1,2,3,4,5]) 53 print (x.flags) 54 C_CONTIGUOUS : True 55 F_CONTIGUOUS : True 56 OWNDATA : True 57 WRITEABLE : True 58 ALIGNED : True 59 WRITEBACKIFCOPY : False 60 UPDATEIFCOPY : False
ndarray.flags 返回 ndarray 对象的内存信息,包含以下属性:
属性 | 描述 |
---|---|
C_CONTIGUOUS (C) | 数据是在一个单一的C风格的连续段中 |
F_CONTIGUOUS (F) | 数据是在一个单一的Fortran风格的连续段中 |
OWNDATA (O) | 数组拥有它所使用的内存或从另一个对象中借用它 |
WRITEABLE (W) | 数据区域可以被写入,将该值设置为 False,则数据为只读 |
ALIGNED (A) | 数据和所有元素都适当地对齐到硬件上 |
UPDATEIFCOPY (U) | 这个数组是其它数组的一个副本,当这个数组被释放时,原数组的内容将被更新 |