一、创建 ndarray
- ndarray 是 Numpy 中表达式数组的重要类型
1.1 使用 np.array() 创建
- 参数为列表:[1, 2, 3, 4, 5]
注意:
- numpy 默认 ndarray 的所有元素的类型都是相同的
- 如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str > float > int
- ndarray 的常见数据类型:
- int:int8、uint8、int32、int64
- float:float16、float32、float64
- str:字符串
案例
data = [1, 4, 8, 16]
n = np.array(data)
# 输出 array([ 1, 4, 8, 16])
# 查看类型
type(n)
# 输出:numpy.ndarray
# 查看形状
n.shape
# 输出:(4,)
1.2 使用 np 的 routines 函数创建
1.2.1 np.ones(shape, dtype=None, order=‘C’)
- 创建一个所有元素都为1的多维数组
参数说明:
- shape:形状
- dtype=None:元素类型
- order:{‘C’, ‘F’},可选,默认值:C 是否在内存中以行主(C - 风格)或 列主(Fortran - 风格)顺序存储多维数据,一般默认即可
案例
n = np.ones(shape=(3, 4), dtype=np.int16)
n
# 输出
"""
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]], dtype=int16)
"""
n = np.ones(shape=(3, 4, 5), dtype=np.int16)
n
# 输出
"""
array([[[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]],
[[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]],
[[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]]], dtype=int16)
"""
1.2.2 np.zero(shape, dtype=float, order=‘C’)
- 创建一个所有元素都为 0 的多维数组
参数说明
- shape:形状
- dtype=None:元素类型
案例
n = np.zeros((2, 3), dtype=np.int16)
n
# 输出
"""
array([[0, 0, 0],
[0, 0, 0]], dtype=int16)
"""
1.2.3 np.full(shape, fill_value, dtype=None, order=‘C’)
- 创建一个所有元素都为指定元素的多维数组
参数说明
- shape:形状
- fill_value:填充值
- dtype=None:元素类型
案例
n = np.full(shape=(2, 3), fill_value=2)
n
# 输出
"""
array([[2, 2, 2],
[2, 2, 2]])
"""
1.2.4 np.eye(N, M=None, k=0, dtype=float)
- 对角线为1,其他位置为 0 的二维数组
参数说明
- N:行数
- M:列数,默认为 None,表示和行数一样
- k=0:向右偏移 0 个位置
- dtype=None:元素类型
案例
# 对角线为1 其他位置为 0 的二维数组
# 单位矩阵:主对角线都为1,其他都是 0
n = np.eye(3, 3, dtype=np.int16)
n
# 输出
"""
array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]], dtype=int16)
"""
# k=2:向右偏移2个位置
n = np.eye(4, 4, k=2, dtype=np.int16)
n
"""
array([[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 0, 0, 0],
[0, 0, 0, 0]], dtype=int16)
"""
# k=-2:向左偏移2个位置
n = np.eye(4, 4, k=-2, dtype=np.int16)
n
"""
array([[0, 0, 0, 0],
[0, 0, 0, 0],
[1, 0, 0, 0],
[0, 1, 0, 0]], dtype=int16)
"""
1.2.5 np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
- 创建一个等差数列
参数说明
- start:开始值
- stop:结束值
- num=50:等差数列中默认有50个数
- endpoint=True:是否包含结束值
- retstep=False:是否返回等差值(步长)
- dtype=None:元素类型
案例
# 等差数列
n = np.linspace(0, 100, num=51, dtype=np.int16)
n
# 输出
"""
array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50,
52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100],
dtype=int16)
"""
# endpoint=False 不包含结束值
n = np.linspace(0, 100, num=51, dtype=np.int16, endpoint=False)
n
"""
array([ 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
33, 35, 37, 39, 41, 43, 45, 47, 49, 50, 52, 54, 56, 58, 60, 62, 64,
66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98],
dtype=int16)
"""
# retstep=True 显示步长
n = np.linspace(0, 100, num=51, retstep=True, dtype=np.int16)
n
"""
(array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50,
52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100],
dtype=int16),
2.0)
"""
1.2.6 np.arange([start, ]stop, [step, ] dtype=None)
- 创建一个数值范围的数组
- 和Python 中range 功能类似
参数说明
- start:开始值(可选)
- stop: 结束值(不包含)
- step: 步长(可选)
- dtype=None:元素类型
案例
n = np.arange(10)
n
# 输出
"""
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
"""
n = np.arange(2, 10, 2)
n
# 输出
"""
array([2, 4, 6, 8])
"""
1.2.7 np.random.randint(low, high=None, size=None, dtype=‘l’)
- 创建一个随机整数的多维数组
参数说明
- low: 最小值
- high=None: 最大值
- high=None时,生成的数值在[0, low) 区间内
- 如果使用 high这个值,则生成的数值在[low, high)区间
- size=None: 数组形状,默认只输出一个随机值
- dtype=None:元素类型b
案例
# 随机整数,范围:[0, 3)
n = np.random.randint(3, 10)
n
# 输出 6
# 随机整数:一维
n = np.random.randint(3, 10, size=6)
n
# 输出
"""
array([5, 7, 3, 9, 7, 6])
"""
# 随机整数:二维
n = np.random.randint(3, 10, size=(3, 4))
n
# 输出
"""
array([[4, 5, 9, 4],
[8, 7, 3, 9],
[8, 8, 3, 9]])
"""
# 随机整数:三维
n = np.random.randint(3, 256, size=(5, 4, 3))
n
# 输出
"""
array([[[250, 236, 105],
[ 41, 83, 186],
[ 75, 238, 185],
[ 64, 60, 152]],
[[ 97, 84, 187],
[ 54, 15, 113],
[ 29, 251, 151],
[124, 255, 31]],
[[220, 140, 196],
[231, 25, 107],
[207, 226, 188],
[192, 151, 210]],
[[ 56, 31, 182],
[231, 229, 174],
[174, 183, 39],
[159, 254, 208]],
[[176, 103, 38],
[175, 52, 232],
[ 6, 54, 8],
[204, 242, 33]]])
"""
1.2.8 np.random.randn(d0, d1, …, dn)
- 创建一个服从标准正态分布的多维数组 | 标准正态分布又称为 u 分布,是以0为均值,以1为标准差的正态分布,记为 N(0, 1) 标准正态分布,在0左右出现的概率最大,越远离出现的概率越低
- 创建一个所有元素都为1的多维数组
参数说明
- dn:第 n 个维度的值
案例
n = np.random.randn()
n
# 输出
"""
0.43208472995839586
"""
n = np.random.randn(10)
n
# 输出
"""
array([-1.61011417, -1.20412098, -1.14859825, 0.57416687, 0.10972571,
2.22336742, 0.60027126, 0.0790297 , 0.25704986, 0.43733903])
"""
n = np.random.randn(5, 3, 4)
n
# 输出
"""
array([[[-0.59266464, -1.41032868, -0.66795804, 2.10874648],
[ 0.86203801, 2.15815146, -0.77780545, 0.79099002],
[-1.50917763, 0.20588002, -0.13462768, 0.08084883]],
[[ 0.24952584, 1.76607996, -1.01216984, -0.39144301],
[-0.31004009, 0.16360959, -2.84586476, -1.65765614],
[ 1.02934158, -1.2893857 , -0.00532093, -0.08730691]],
[[-3.52627867, -1.01049899, -0.98890288, -2.01056535],
[ 0.18090506, 1.70731921, 1.14165572, -1.84944679],
[-1.96011023, -0.59342939, -0.11321104, 0.07079039]],
[[-2.13172668, 1.43002297, -0.46821835, 0.61493562],
[-0.35164459, -1.2965888 , -1.52827137, -0.57103889],
[ 0.90352185, -0.51997281, 0.33191387, -0.42465242]],
[[-0.97435604, -1.1134363 , 0.663516 , 0.43412083],
[ 0.87036026, 3.11842392, -0.19740484, -0.02241018],
[ 0.18711381, 0.44299792, 0.112106 , 1.1274216 ]]])
"""
1.2.9 np.random.normal(loc=0.0, scale=1.0, size=None)
- 创建一个服从正态分布的多维数组
参数说明
- loc=0.0: 均值,对应着正态分布的中心
- scale: 标准差,对应分布的宽度, scale 越大,正态分布的曲线越矮胖, scale 越小,曲线越高瘦
- size=None:数组形状
案例
n = np.random.normal(loc=100, scale=10, size=3)
n
# 输出
"""
array([99.57230214, 95.69101019, 92.41164979])
"""
1.2.10 np.random.random(size=None)
- 创建一个元素为 0~1(左闭右开)的随机数的多维数组
参数说明
- size=None:数组形状
案例
n = np.random.random(size=(3, 4))
n
# 输出
"""
array([[0.19935414, 0.89167517, 0.61077615, 0.57980079],
[0.135628 , 0.11782525, 0.97452393, 0.58147522],
[0.16983962, 0.6139807 , 0.84035926, 0.87385295]])
"""
1.2.11 np.random.rand(d0, d1, …, dn)
- 创建一个元素为 0 ~1(左闭又开)的随机数的多维数组
- 和 np.random.random 功能类似,掌握其中一个即可
参数说明
- dn:第 n个维度的数值
案例
n = np.random.rand(3, 4)
n
# 输出
"""
array([[0.56982685, 0.17599003, 0.33233895, 0.18152614],
[0.28209208, 0.35362469, 0.21779401, 0.38818379],
[0.81703864, 0.30211352, 0.88655855, 0.21970974]])
"""
二、ndarray 的属性
- ndim: 维度
- shape: 形状(各维度的长度)
- size:总长度
- dtype:元素类型
三、ndarray 基本操作
3.1 索引
一维与列表完全一致,多维时同理
案例
l = [1, 2, 3, 4, 5, 6]
l[0], l[-1]
# 输出:
"""
(1, 6)
"""
# 二维
n = np.random.randint(0, 10, size=(4, 5))
n
"""
array([[8, 5, 3, 9, 7],
[4, 6, 1, 5, 4],
[6, 1, 5, 5, 2],
[8, 1, 2, 5, 9]])
"""
# 找到最后一个数
n[3][4]
n[-1][-1]
# 简写
n[-1][-1]
# 三维
n = np.random.randint(0, 100, size=(4, 5, 6))
n
"""
array([[[50, 20, 29, 36, 62, 0],
[ 9, 1, 30, 30, 91, 56],
[93, 90, 49, 28, 67, 76],
[69, 34, 47, 8, 89, 49],
[56, 94, 15, 30, 92, 92]],
[[43, 33, 86, 35, 45, 43],
[76, 27, 71, 86, 62, 88],
[69, 95, 6, 66, 56, 91],
[67, 50, 14, 32, 54, 53],
[22, 15, 29, 76, 46, 1]],
[[21, 39, 3, 16, 19, 67],
[ 3, 33, 92, 60, 53, 5],
[15, 22, 85, 13, 60, 8],
[32, 18, 76, 80, 28, 78],
[58, 65, 47, 4, 94, 12]],
[[ 9, 10, 53, 65, 89, 64],
[45, 12, 71, 75, 93, 93],
[74, 59, 71, 69, 28, 1],
[37, 67, 64, 11, 92, 42],
[ 9, 67, 84, 92, 57, 16]]])
"""
n[1][2][-1]
n[1, 2] = [1, 2, 3, 4, 5, 6]
n
3.2 切片
一维与列表完全一致,多维时同理
案例
# Python 列表中的切片
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
l[2:6] # 切片
l[::-1] # 翻转
# Numpy 数组
n = np.array(l)
n
"""
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
"""
n[2:6], n[::-1]
"""
(array([3, 4, 5, 6]), array([9, 8, 7, 6, 5, 4, 3, 2, 1]))
"""
# 二维或多维
n = np.random.randint(0, 10, size=(6, 8))
n
"""
array([[8, 0, 6, 6, 1, 5, 3, 4],
[1, 5, 0, 3, 5, 9, 1, 2],
[7, 5, 7, 1, 5, 2, 3, 3],
[0, 6, 2, 3, 2, 9, 2, 4],
[8, 5, 0, 4, 9, 5, 9, 8],
[8, 3, 2, 2, 6, 6, 3, 8]])
"""
# 行
# 取一行
n[0]
# 取连续多行:切片
print(n[1:4])
# 取不连续的多行:中括号
print(n[[1, 2, 4]])
# 列
# 取一列
print(n[:, 0]) # 取所有的行,和第0列
# 取连续多列
print(n[:, 2:5])
# 取不连续多列:中括号
print(n[:, [1, 3, 4]])
n = np.random.randint(0, 100, size=(5, 6))
n
# 行翻转
n[::-1]
# 列翻转
n[:,::-1]
3.3 变形
使用reshape 函数
n = np.arange(1, 21)
n
"""
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20])
"""
# reshape:将数组改变形状
n.shape
# 变成二维
n2 = np.reshape(n, (4, 5))
n2
n2.shape
n2.reshape((5, 4))
3.4 级联
np.concatenate()
- 参数是列表或元组
- 级联的数组维度必须相同
- 可通过axis 参数改变级联的方向
n1 = np.random.randint(0, 100, size=(3, 5))
n2 = np.random.randint(0, 100, size=(3, 5))
display(n1, n2)
# 级联合并
np.concatenate((n1, n2)) # 默认是上下合并
np.concatenate((n1, n2), axis=0) # 上下合并 axis=0 表示:第一个维度(行)
# 左右合并 axis=1 表示第二个维度(列)
np.concatenate((n1, n2), axis=1)
np.hstack 与 np.vstack
- 水平级联与垂直级联
# np.hstack: 水平级联,左右合并
np.hstack((n1, n2))
# np.vstack:垂直级联,上下合并
np.vstack((n1, n2))
3.5 数组的拆分
- np.split
- np.vsplit
- np.hsplit
n = np.random.randint(0, 100, size=(6, 4))
n
# 垂直拆分,平均拆成3份
np.vsplit(n, 3)
np.vsplit(n, (1, 2,4))
# 水平拆分
np.hsplit(n, 2)
# split:可以做水平拆分或者垂直拆分
# axis=0 行
# axis=1 列
np.split(n, 2) # 默认按行拆分
np.split(n, 2, axis=1) # 按列拆分
# 图片拆分
# 读取图片
# 图片:其实是数字组成的,三维数组
# RGB 0~255
cat = plt.imread('huawei.jpg')
cat
cat.shape
cat2 = cat[:-1]
cat2.shape
#plt.imshow(cat2)
cat3 = np.split(cat2, 3)
cat3[0]
plt.imshow(cat3[0])
# 水平拆分
cat4 = np.split(cat2, 2, axis=1)
cat4
plt.imshow(cat4[0])
3.6 副本/复制/拷贝
copy() 函数创建副本
# 赋值:用的是同一个内存
n = np.arange(10)
n2 = n
n2[0] = 100
display(n, n2)
# 拷贝
n1 = np.arange(10)
n1
n2 = n1.copy()
n2[0] = 100
display(n1, n2)
n = np.random.randint(0, 100, size=(2, 3))
n2 = n.copy()
n2[0, 0] = 100
display(n, n2)
四、numpy 聚合操作
- np.sum() 求和
- np.min() 最小值
- np.max() 最大值
- np.mean() 平均值
- np.average() 平均值
- np.median() 中位数
- np.percentile 百分位数
- np.argmin() 最小值对应的下标
- np.argmax() 最大值对应的下标
- np.std() 标准差
- np.var() 方差
- np.power() 次方,求幂
- np.argwhere() 按条件查找
4.1 求和 np.sum
n = np.arange(10)
n
"""
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
"""
np.sum(n)
n = np.random.randint(0, 10, size=(3, 5))
n
np.sum(n) # 所有数的和
# axis=0:表示行
np.sum(n, axis=0)
# axis=1:表示列
np.sum(n, axis=1)
n = np.random.randint(0, 10, size=(3, 5))
n
np.max(n) # 最大值
np.min(n) # 最小值
np.mean(n) # 平均值
np.average(n) # 平均值
np.median(n) # 中位数
np.percentile(n, q=50) #百分位数,q=50表示中位数
n = n.reshape(-1)
display(n)
np.argmax(n) # 第一个最大值对应的下标
np.argmin(n) # 第一个最小值对应的下标
np.argwhere(n == np.max(n)) # 按条件找到所有最大值的下标
np.power(n, 3)
np.std(n) # 标准差
np.var(n) # 方差
4.2 np.sum 和 np.nansum (nan:not a number)
- nan: 数值类型,not a number:不是一个正常的数值,表示 空
- np.nan:float 类型
n = np.array([1, 2, 3, np.nan])
n
"""
array([ 1., 2., 3., nan])
"""
np.sum(n) # 无法求出和
np.nansum(n) # 排除掉 nan ,在求和
五、矩阵操作
5.1 算术运算符
- 加减乘除
n = np.random.randint(0, 10, size=(4, 5))
n
"""
array([[6, 8, 5, 2, 4],
[2, 2, 2, 6, 6],
[0, 0, 2, 2, 6],
[0, 0, 5, 1, 8]])
"""
n + 10 # 加
n - 10 # 减
n * 10 # 乘
n / 10 # 除
n // 2 # 整除
n ** 2 # 次方
n % 2 # 余数
n1 = np.random.randint(0, 10, size=(4, 5))
n2 = np.random.randint(0, 10, size=(4, 5))
display(n1, n2)
n1 + n2
5.2 线性代数
- 矩阵积 np.dot()
- 第一个矩阵的列数 等于 第二个矩阵的行数
n1 = np.random.randint(0, 10, size=(3, 4))
n2 = np.random.randint(0, 10, size=(4, 5))
np.dot(n1, n2)
5.3 广播机制
【重要】ndarray 广播机制的两条规则
- 规则一:为缺失的维度补维度
- 规则二:缺失元素用已有值填充
例1: m = np.ones((2, 3)) a = np.arange(3) 求 m+a
m = np.ones((2, 3))
a = np.arange(3)
display(m, a)
m + a
a = np.arange(3).reshape(3, 1)
b = np.arange(3)
display(a, b)
a + b
5.4 其他常见数学操作
- abs(绝对值)
- sqrt(平方根)
- square(平方)
- exp(指数 e=2.71828…)
- log (自然指数:以 e 为 底的对数, ln3)
- sin(正弦)
- cos(余弦)
- tan(正切)
- round
- ceil
- floor
- cumsum
5.5 快速排序
np.sort() 与 ndarray.sort()都可以,但是有区别:
- np.sort() 不改变输入
- ndarray.sort() 本地处理,不占用空间,但改变输入
n1 = np.random.randint(0, 10, size=6)
n1
# 不改变原数组
n2 = np.sort(n1)
n2
n3 = np.random.randint(0, 10, size=6)
n3
n3.sort()
n3
5.6 ndarray 文件操作
保存数组
- save:保存 ndarray 到一个 npy 文件
- savez: 将多个array 保存到一个文件
x = np.array(5)
y = np.arange(10, 20)
# save
np.save('x', x)
#savez
np.savez('arr.npz', xarr=x, yarr=y)
读取数组
np.load('x.npy')
np.load('arr.npz')['yarr']