ndarray 对象

numpy 定义了一个 ndarray 对象,表示一个多维数组,numpy 操作都是基于 ndarray 进行

使用 np.array 方法创建一个 ndarray 对象

1
np.array(object, dtype = None, copy = True, order = None, ndmin = 0)
  • object:传入的序列对象,可以是列表或元组

  • dtype:通过该参数设置数组的数据类型

  • copy:设置该 ndarray 对象能否被复制

  • order:设置数组的存储顺序,可选 C(行序列),F(列序列),A(默认)

  • ndim:指定数组的维度

dtype 对象

dtype 对象用于描述数组元素的数据类型,大小和字节顺序

使用 np.dtype 方法创建一个 numpy 数据类型

1
numpy.dtype(object, align, copy)
  • object:要转换为的数据类型对象
  • align:如果为 true,则该类型使用字节对齐
  • copy:复制 dtype 对象 ,如果为 false,则是对内置数据类型对象的引用

使用数据类型对象定义结构化数据,可以使 ndarray 实现字典的索引方式

1
2
3
4
5
import numpy as np
teacher = np.dtype([('name','S20'), ('age', 'i1'), ('salary', 'f4')])
#将其应用于ndarray对象
b = np.array([('ycs', 32, 6357.50),('jxe', 28, 6856.80)], dtype = teacher)
print(b['name']) # 字符串类型只支持ASCII

数组属性

以下是 ndarray 对象的一些常用属性

  • ndarray.shape:返回一个以数组维度大小为元素的元组,从下标 0 到 n,可称为轴 0 到轴 n,可以直接设置该属性或使用 reshape 函数来改变维度

    1
    2
    3
    4
    5
    6
    7
    8
    import numpy as np 
    a = np.array([[1,2,3],[4,5,6]])
    a.shape = (3,2)
    print (a)

    # 使用reshape函数,reshape函数不会创建副本,依然使用原来的引用,因此修改b元素,a元素也会改变
    b = a.reshape(3,2)
    print (b)
  • ndarray.ndim:返回数组的维度个数,即 shape 返回值的元素个数,该属性只读

  • ndarray.itemsize:返回每个元素的字节大小

  • ndarray.flags:返回数组的内存信息

  • ndarray.size:数组的元素个数

  • ndarray.dtype:数组的数据类型

创建数组

基本数组

  • empty

    使用 np.empty() 创建一个未初始化的数组

    1
    np.empty(shape, dtype = float, order = 'C')
    • shape:指定数组的形状,传入一个元组
    • dtype:指定数组的数据类型
    • order:指定数组的存储顺序,可选 C(行序列),F(列序列),A(默认)
  • zeros

    使用 np.zeros() 创建一个所有值均为 0 的数组,参数同 empty()

  • ones

    使用 np.zeros() 创建一个所有值均为 1 的数组,参数同 empty()

  • asarray

    从已有的 ndarray 创建数组,与 array() 不同的是 array() 返回的是一个副本,asarray() 返回的是一个引用,原数组修改或返回的新数组修改都会改变数据

    1
    numpy.asarray(a, dtype = None, order = None)
  • frombuffer

    使用指定的缓冲区创建数组

    1
    np.frombuffer(buffer, dtype = float, count = -1, offset = 0)
    • buffer:将任意对象转换为流的形式读入缓冲区
    • dtype:数组的数据类型,默认是 float32
    • count:要读取的数据数量,默认为 -1 表示读取所有数据
    • offset:读取数据的起始位置,默认为 0
  • fromiter

    将可迭代对象转化为 ndarray 数组,返回一个一维数组

    1
    np.fromiter(iterable, dtype, count = -1)
    • iterable:可迭代对象
    • dtype:数组的数据类型
    • count:读取的数据数量,默认为 -1,读取所有数据

区间数组

  • arange

    指定一个数值范围创建 ndarray

    1
    np.arange(start, stop, step, dtype)
    • start:起始数值
    • stop:终止值,范围为左闭右开
    • step:步长值,默认为 1
    • dtype:数据类型
  • linspace

    创建等差数列 ndarray

    1
    np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
    • start:数值区间的起始值
    • stop:数值区间的终止值
    • num:表示数值区间内要生成多少个均匀的样本。默认值为 50
    • endpoint:默认为 True,表示数列包含 stop 终止值,反之不包含
    • retstep:默认为 False,表示生成的数组中会显示公差(间距),反之不显示
    • dtype:数组元素值的数据类型
  • logspace

    创建等比数列 ndarray

    1
    np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
    • start,stop:起始值,终止值
    • num:生成的数组元素个数,默认为 50
    • endpoint:设置是否包含终止值,默认为 True
    • base:设置对数函数的底数,默认为 10
    • dtype:指定数组的数据类型

索引与切片

一维数组

使用内置函数 slice() 创建一个切片对象,再对 ndarray 切片

1
2
3
4
arr = np.arange(10)
s = slice(2, 7, 2) # 创建切片对象
arr[s] # 访问切片内容
# array([2, 4, 6])

使用 : 索引

对于一维数组,其基本格式为 [start:stop:step],start 和 stop 为左闭右开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
arr = np.arange(10)
arr
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

arr[2:7:2]
# array([2, 4, 6])

arr[2:] # 从[2]开始之后的所有项
# array([2, 3, 4, 5, 6, 7, 8, 9])

arr[:7] # 在[7]之前的所有项,不包括[7]
# array([0, 1, 2, 3, 4, 5, 6])

arr[:] # 等价于arr[::],取当前维度所有项
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

arr[::2] # 按步长切片
# array([0, 2, 4, 6, 8])

多维数组切片

使用 : 索引,按从外到内的顺序,对每一个维度进行切片,基本格式为 start:stop:step,不同维度用逗号隔开

1
2
arr[2:4, :] # 二维,取第三行和第四行
arr[:, 2:4] # 取第三列和第四列

使用省略号来表示某一维度的全索引,等价于 :::

1
2
3
4
5
# 二维
arr[2:4, ...] # 取第三行和第四行
arr[2, ...] # 取第三行
arr[..., 1:4] # 取第二列到第四列
arr[..., 1] # 取第二列

高级索引

numpy 不止可以通过单个整数索引,也可以通过其他方式来索引,主要有整数数组索引、布尔索引

整数数组索引

使用一个数组来索引另一个数组

1
2
3
4
x = np.array([[1,  2],  [3,  4],  [5,  6]])
# 行维度上访问[0, 1, 2],列维度上访问[0, 1, 0]
# 对应组成坐标(0, 0), (1, 1), (2, 0)
x[[0, 1, 2], [0, 1, 0]] # [1 4 5]

索引数组的维度影响结果的维度

1
2
3
4
5
6
7
x = np.array([[1,  2],  [3,  4],  [5,  6]])
# 索引数组为一维,结果是一维
x[[0, 1, 2, 2], [0, 1, 0, 1]] # array([1, 4, 5, 6])
# 索引数组为二维,则结果也是二维
x[[[0, 1], [2, 2]], [[0, 1], [0, 1]]]
# array([[1, 4],
# [5, 6]])

索引数组可以与 :... 配合

1
2
3
4
x = np.array([[1,  2],  [3,  4],  [5,  6]])
x[1:3, [0, 1]]
# array([[3, 4],
# [5, 6]])

使用一个索引数组只访问一个维度

1
2
3
4
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
x[[1, 2]] # 一个数组只访问行维度
# array([[3, 4, 5],
# [6, 7, 8]])

布尔索引

使用逻辑表达式进行索引

1
2
3
x = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]]) 
x[x > 5] # 取数组中大于5的元素
# array([ 6, 7, 8, 9, 10, 11])

广播机制

广播机制用于解决不同形状的数组之间进行运算的问题

广播机制经过以下步骤

  1. 补齐:以两个数组中的最大 ndim 值为准,其他数组在高维上(shape 元组左侧)补 1

    例如,a 数组的 shape 为 (4, 3),b 数组的 shape 为 (3,),则 b 数组补齐为 (1, 3)

  2. 比较:依次比较两个数组的各个维度大小,若不相等且其中一个维度值不为 1,则报错

    例如,a 数组的 shape 为 (4, 3),b 数组的 shape 为 (3, 1),比较 shape[0] 时,不相等且其中一个值不为 1,报错

    例如,a 数组的 shape 为 (4, 3),b 数组的 shape 为 (1, 3)

    • 比较 shape[0],其中一个值为 1,通过
    • 比较 shape[1],二者相等,通过
  3. 扩展:在比较时,将维度大小为 1 的维度对应的元素复制多个,使其维度大小与另一数组对应维度大小相等

    例如,a 数组的 shape 为 (4, 3),b 数组为 [[0, 1, 2]],shape 为 (1, 3),维度大小为 1 维度对应的元素为 [0, 1, 2],复制该元素,将维度大小扩展到 4,即 b 数组变为 [[0, 1, 2], [0, 1, 2], [0, 1, 2], [0, 1, 2]],shape 变为 (4, 3)

  4. 运算:两个数组经过以上处理后,若 shape 相同,则可以运算

e.g. x = [0, 1, 2], y = [[0], [1], [2]]

  • x 的 shape 为 (1, 3),扩展为 (3, 3),数组变为 [[0, 1, 2], [0, 1, 2], [0, 1, 2]]
  • y 的 shape 为 (3, 1),扩展为 (3, 3),数组变为 [[0, 0, 0], [1, 1, 1], [2, 2, 2]]
1
2
3
4
5
6
7
x = np.array([0, 1, 2])
y = np.array([0, 1, 2])
y = y.reshape((3, 1))
x + y
# array([[0, 1, 2],
# [1, 2, 3],
# [2, 3, 4]])

遍历数组

使用 numpy 的 nditer 迭代器对象,配合 for 进行遍历,迭代器的遍历顺序与数组的存储顺序一致

1
2
3
4
5
6
7
import numpy as np
a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
# 使用nditer迭代器,并使用for进行遍历
# 若传入a.T,存储顺序不改变,依然按行序遍历
for x in np.nditer(a):
print(x)
  • order:指定迭代器的遍历顺序
  • op_flags:表示能否在遍历时修改数据,默认为 readonly,可选 readwritewriteonly

遍历多个数组时,可以触发广播机制

1
2
3
4
5
6
7
8
9
10
import numpy as np
a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
print (a)
b = np.array([1, 2, 3, 4], dtype = int)
print (b)
# 广播迭代
for x,y in np.nditer([a,b]): # 传入两个数组组成的列表
print ("%d:%d" % (x,y),end=",")
# 0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4

数组操作

展平

名称 描述
ndarray.reshape() 在不改变数组元素的条件下,修改数组的形状
- arr:输入数组
- newshape:元组,新形状
ndarray.flat 返回一个迭代器,可以用 for 循环遍历其中的每一个元素
ndarray.flatten() 以一维数组的形式返回一份数组的副本
- order:指定展开顺序,可选 C(按行)、F(按列)、A(原顺序)、K(存储顺序)
np.ravel() 返回一个展开的一维数组视图
- arr:输入数组
- order:指定展开顺序,可选 C(按行)、F(按列)、A(原顺序)、K(存储顺序)

轴操作

名称 描述
np.transpose() 将数组的维度值进行对换
- arr:输入数组
- axes:整数数组,指定要对换的轴
ndarray.T transpose 方法相同
np.rollaxis() 将指定的轴移动到指定位置
- arr:输入数组
- axis:整数,指定移动的轴
- start:整数,指定移动的位置
np.swapaxes() 交换指定的两个轴
- arr:输入数组
- axis1:整数,指定交换的第一个轴
- axis2:整数,指定交换的第二个轴

维度操作

名称 描述
np.broadcast() 生成一个模拟广播结果的对象
- arr1:指定要广播的数组
- arr2:指定数组作为广播基准
np.broadcast_to() 将数组广播为新的形状,返回一个只读视图
- arr:输入数组
- shape:元组,广播目标形状
np.expand_dims() 在数组中插入新的轴
- arr:输入数组
- axis:整数,指定插入位置
np.squeeze() 默认删除所有维度大小为 1 的轴
- arr:输入数组
- axis:整数或整数元组,指定需要删除的轴,指定的轴的维度大小必须为 1,否则报错

连接数组

名称 描述
np.concatenate() 沿指定轴连接数组
- arrs:包含数组的元组
- axis:整数,指定连接轴,默认为 0
np.stack() 生成新的轴堆叠数组,轴的维度大小是输入数组的个数
- arrs:包含数组的元组
- axis:整数,指定生成轴的位置
np.hstack() 水平堆叠序列中的数组(列方向)
- arrs:包含数组的元组
np.vstack() 竖直堆叠序列中的数组(行方向)
- arrs:包含数组的元组

分割数组

名称 描述
np.split() 将数组分割为多个子数组
- arr:输入数组
- indices_or_sections:整数或数组,输入整数时,表示分割子数组个数,输入数组时,表示分割位置,左开右闭
- axis:整数,在指定轴上切分
np.hsplit() 将一个数组水平分割为多个子数组(按列)
- arr:输入数组
- sections:整数,表示分割子数组个数
np.vsplit() 将一个数组垂直分割为多个子数组(按行)
- arr:输入数组
- sections:整数,表示分割子数组个数

元素修改

名称 描述
np.resize() 修改数组大小,返回指定 shape 的新数组
- arr:输入数组
- shape:元组,新形状
np.append() 默认将数组展平后,在末尾添加元素值,返回新数组
- arr:输入数组
- values:插入值,除了 axis 指定的插入轴,其他轴的维度大小要与 arr 相等
- axis:整数,指定插入轴
np.insert() 默认将数组展平,将值插入到指定数组指定位置,返回新数组
- arr:输入数组
- index:整数,指定插入位置
- values:插入值,可广播为 arr 形状
- axis:整数,指定插入的轴
np.delete() 默认将数组展平后,删除指定位置的元素,返回新数组
- arr:输入数组
- index:整数,指定删除位置
- axis:整数,指定删除的轴
np.unique() 将一个数组展平后,删除数组中重复的元素,返回新数组
- arr:输入数组
- return_index:若为 True,则返回新数组元素在原数组中的索引
- return_inverse:若为 True,则返回原数组元素在新数组中的索引
- return_counts:若为 True,则返回去重后的数组元素在原数组中出现的次数

位运算

函数 描述
np.bitwise_and() 按位与,对数组元素执行位与操作
np.bitwise_or() 按位或,对数组元素执行位或操作
np.bitwise_xor() 按位异或
np.bitwise_not() 按位取反
np.invert() 按位取反
np.left_shift() 左移位运算,向左移动二进制表示的位
np.right_shift() 右移位运算,向右移动二进制表示的位
bin() 返回指定数值的二进制形式

字符串处理

字符串处理函数定义在 numpy.char 类中,函数的处理对象是 dtypestring_unicode_ 的字符串数组

函数名称 描述
add() 输入多个字符串数组,对数组中相应位置的字符串做连接操作
multiply() 将一个字符串复制多次后连接,返回连接字符串副本
center() 用于居中字符串,并将指定的字符填充在原字符串的左右两侧
capitalize() 将字符串第一个字母转换为大写
title() 将字符串的每个单词的第一个字母转换为大写形式
lower() 将数组中所有的字符串转换为小写
upper() 将数组中所有的字符串转换为大写
split() 指定分隔符对字符串进行分割,并返回一个数组序列,默认分隔符为空格
splitlines() 以换行符作为分隔符来分割字符串,并返回数组序列
strip() 删除字符串开头和结尾处的指定字符
join() 指定一个分隔符或一个分隔符列表来连接数组中的所有字符串,分隔符列表与每个字符串一一对应
replace() 用新的字符串替换原字符串中指定的子串
decode() 用指定的编码格式对数组中的字符串依次执行解码操作
encode() 用指定的编码格式对数组中的字符串依次执行编码操作

数学函数

三角函数

名称 描述
np.sin() 正弦函数
np.cos() 余弦函数
np.tan() 正切函数
np.arcsin() 反正弦函数
np.arccos() 反余弦函数
np.arctan() 反正切函数
np.degrees() 将弧度值转换为角度值
x * np.pi / 180 将角度值转换为弧度值

舍入函数

名称 描述
np.around() 返回指定数的四舍五入值,decimals 参数指定舍入的小数位数
np.floor() 向下取整
np.ceil() 向上取整

算术运算

名称 描述
np.add() 两个数组对应元素相加
np.subtract() 两个数组对应元素相减
np.multiple() 两个数组对应元素相乘
np.divide() 两个数组对应元素相除
np.reciprocal() 返回数组元素的倒数
np.power() 返回数组对应元素的幂
np.mod() 返回数组对应元素的取余

统计函数

名称 描述
np.amin() 返回数组或沿某个轴的最小值
- arr:输入数组
- axis:整数,指定轴
np.amax() 返回数组或沿某个轴的最大值
- arr:输入数组
- axis:整数,指定轴
np.ptp() 返回数组或沿某个轴上的极差
- arr:输入数组
- axis:整数,指定轴
np.percentile() 返回数组中的百分位数
- arr:输入数组
- q:数值,指定要计算的百分位数
- axis:整数,指定轴
np.median() 返回数组或沿某个轴的中位数
- arr:输入数组
- axis:整数,指定轴
np.mean() 返回数组或沿某一个轴的算术平均值
- arr:输入数组
- axis:整数,指定轴
np.average() 返回数组或沿某个轴的加权平均值
- arr:输入数组
- axis:整数,指定轴
- weights:数值列表,指定每个元素的权重
- returned:若为 True,同时返回权重之和
np.var() 返回数组或沿某个轴的方差
- arr:输入数组
- axis:整数,指定轴
np.std() 返回数组或沿某个轴的标准差
- arr:输入数组
- axis:整数,指定轴

排序和搜索

名称 描述
np.sort() 默认将数组展平后排序,返回一个副本
- arr:输入数组
- axis:沿着指定轴进行排序
- kind:默认为 quicksort,可选 mergesortheapsort
- order:字符串或字符串列表,指定排序字段
np.argsort() 返回沿指定轴上元素升序的索引序列
- arr:输入数组
- axis:整数,指定轴
- kind:默认为 quicksort,可选 mergesortheapsort
- order:字符串或字符串列表,指定排序字段
np.lexsort() 将多个数组的对应位置元素组成数对,对数对进行排序,返回升序的索引序列
- arrs:包含多个数组的元组
- axis:整数,指定轴
np.argmin() 返回某个轴上的最大值的索引
- arr:输入数组
- axis:整数,指定轴
np.argmax() 返回某个轴上的最小值的索引
- arr:输入数组
- axis:整数,指定轴
np.nonzero() 返回数组中非 0 元素的索引序列
- arr:输入数组
np.where() 返回数组中满足条件的元素的索引序列
- condition:使用数组的逻辑表达式
np.extract() 返回数组中满足条件的元素
- condition:使用数组的逻辑表达式
- arr:输入数组

IO 操作

numpy 中提供了一些 IO 函数,用于在文件中读写 ndarray 对象

可操作的文件类型

  • .npy 文件
  • .txt 文件
  • .npz 文件
名称 描述
np.save() 将数组保存 .npy 文件中
- file:字符串,保存后的文件名称,文件后缀为 .npy
- arr:保存的数组
- allow_pickle:若为 True,表示允许使用 pickle 序列化保存数组对象
np.load() .npy 文件、.npz 文件或 pickle 文件中读入数组
- filename:字符串,文件路径
- encoding:字符串,指定编码
- allow_pickle:若为 True,表示允许加载 .npy 文件中的 pickle 对象
np.savez() 将多个数组保存到 .npz 文件中
- file:字符串,保存后的文件名称,文件后缀为 .npz
- args:保存的多个数组,自动命名为 arr_0arr_1
- kwargs:保存的多个数组,通过 key 为数组 value 指定名称
np.savetxt() 将数组保存在 .txt 文件中
- filename:字符串,保存后的文件名称,文件后缀为 .txt
- X:保存的一维或二维数组
- fmt:字符串或字符串列表,指定元素的表示格式
- delimiter:字符串,指定元素之间的分隔符
- newline:字符串,指定换行符
- header:字符串,指定文件开头内容
- footer:字符串,指定文件末尾内容
- comments:字符串,指定注释符号,默认为 #
- encoding:字符串,指定编码
np.loadtxt() .txt 文件中读取数组
- filename:字符串,文件路径
- dtype:dtype 对象,指定元素数据类型
- comments:字符串,指定注释符号,默认为 #
- delimiter:字符串,指定元素分隔符
- skiprows:整数,指定跳过的行数
- usecols:整数或整数序列,指定读取的列
- unpack:若为 True,表示以解包形式返回数组
- ndim:整数,指定返回数组的最低维度,可选 0,1,2
- encoding:字符串,指定编码
- max_rows:整数,指定读取的最大行数,不包含 skiprows
- converters:函数或字典,对数组的每列执行指定转换函数,或对字典中的指定列数执行对应的转换函数