Numpy基础
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])
广播机制
广播机制用于解决不同形状的数组之间进行运算的问题
广播机制经过以下步骤
补齐:以两个数组中的最大
ndim
值为准,其他数组在高维上(shape元组左侧)补1例如,a数组的shape为(4, 3),b数组的shape为(3,),则b数组补齐为(1, 3)
比较:依次比较两个数组的各个维度大小,若不相等且其中一个维度值不为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]
,二者相等,通过
- 比较
扩展:在比较时,将维度大小为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)运算:两个数组经过以上处理后,若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
,可选readwrite
,writeonly
遍历多个数组时,可以触发广播机制
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
类中,函数的处理对象是dtype
为string_
或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 ,可选mergesort ,heapsort - order:字符串或字符串列表,指定排序字段 |
np.argsort() | 返回沿指定轴上元素升序的索引序列 - arr:输入数组 - axis:整数,指定轴 - kind:默认为 quicksort ,可选mergesort ,heapsort - 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_0 、arr_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:函数或字典,对数组的每列执行指定转换函数,或对字典中的指定列数执行对应的转换函数 |