NumPy 使用教学
NumPy 是 Python 中用于科学计算的基础库,它提供了高性能的多维数组对象以及用于处理这些数组的工具。下面将结合多个代码文件,详细介绍 NumPy 的各种用法。
1. 创建数组
1.1 从列表创建数组
import numpy as np
# 一维数组
list1 = [1,2,3,4,5]
print(list1)
v = np.array(list1)
print(v)
# 二维数组[多个一维数组构成]
m = np.array([list1,list1,list1])
print(m)
# 三维数组[多个二维数组构成]
z = np.array([[list1,list1,list1],[list1,list1,list1],[list1,list1,list1]])
print(z)
z = np.array([m,m,m])
print(z)
# 更高维的
y = np.array([z,z,z])
print(y)
运行结果:首先打印出原始列表 list1
,然后依次打印出一维数组 v
、二维数组 m
、三维数组 z
和更高维数组 y
。
函数解析:np.array()
函数用于将 Python 列表转换为 NumPy 数组。可以传入一维、二维或更高维的列表来创建相应维度的数组。
1.2 创建特殊的数组
import numpy as np
# 创建全为 0 的数组
a = np.zeros(5)
b = np.zeros((2,2))
c = np.zeros((3,2,2))
print(a, '\n', b, '\n', c)
# 创建全为 1 的数组
d = np.ones(5)
e = np.ones((2,2))
f = np.ones((2,2,2))
# 创建全为 2 的数组……矩阵中全部填充指定的数据
g = np.full((2,2,2),5)
print(g)
# 小补充: 5 行×7 列的类单位矩阵(对角矩阵)
h = np.eye(5,7)
print(h)
运行结果:打印出全 0 数组 a
、b
、c
,全 1 数组 d
、e
、f
,全 5 数组 g
以及 5 行 7 列的类单位矩阵 h
。
函数解析:
np.zeros()
:创建指定形状的全 0 数组。np.ones()
:创建指定形状的全 1 数组。np.full()
:创建指定形状并填充指定值的数组。np.eye()
:创建指定行数和列数的类单位矩阵(对角矩阵)。
2. 数组的基本属性
import numpy as np
list1 = [1,2,3,4,5]
m = np.array([list1,list1,list1])
a = m.shape
b = m.ndim
c = m.size
d = m.dtype
print("二维数组")
print(type(m))
print(a)
print(b)
print(c)
print(d)
# 三维数组
print("三维数组")
z = np.array([m,m,m])
print(z.shape)
print(z.ndim)
print(z.size)
print(type(z))
print(z.dtype)
运行结果:先打印二维数组 m
的类型、形状、维度、元素个数和元素类型,再打印三维数组 z
的相关信息。
函数解析:
shape
:返回数组的形状,用元组表示。ndim
:返回数组的维度。size
:返回数组中元素的个数。dtype
:返回数组中元素的类型。
3. 数组的升维与降维
3.1 数组的升维
import numpy as np
list1 = [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8]
v = np.array(list1)
print(v)
# 一维变二维[-1 表示自己计算]【返回一个改变后的矩阵】
r1 = v.reshape(4,4)
print(r1)
r1 = v.reshape(-1,4)
print(r1)
print(r1.ndim)
# 一维变三维
r2 = v.reshape(1,-1,2)
print(r2)
# 二维变三维
r3 = r1.reshape(2,2,4)
print("###")
print(r3)
print("###")
# resize()【不返回计算结果】【直接修改原始数组】
v.resize(4,4)
print(v)
运行结果:先打印一维数组 v
,然后依次打印升维后的二维数组 r1
、三维数组 r2
、r3
,最后打印使用 resize()
修改后的数组 v
。
函数解析:
reshape()
:返回一个具有新形状的数组,原数组不变。-1
作为占位符,让 NumPy 自动计算该维度的大小。resize()
:直接修改原数组的形状。
3.2 数组的降维
import numpy as np
list1 = [1,2,3,4,5,6,7,8]
print(list1)
v = np.array(list1)
print(v)
v = v.reshape(2,2,2)
print(v)
print(v.ndim)
# 将三维降到二维
r1 = v.reshape(1,8)
print(r1)
# 将高维数据转化为一维 ravel()
r2 = v.ravel()
print(r2)
# flatten()
r3 = v.flatten()
print(r3)
# flatten 方法返回的是原数组的副本,这意味着对返回的一维数组所做的任何修改都不会影响原始的多维数组。
# ravel 方法(如果可能)返回的是原始数组的视图,因此对返回的一维数组所做的修改可能会影响原始的多维数组。这是因为 ravel 改变了数组
v = np.array(list1)
print(v)
# 小补充 shape 也可以实现降维
v.shape = (2,4)
print(v)
运行结果:先打印原始列表 list1
和一维数组 v
,然后将 v
变为三维数组并打印,接着依次打印降维后的二维数组 r1
、一维数组 r2
、r3
,最后打印使用 shape
属性修改后的数组 v
。
函数解析:
reshape()
:用于将数组转换为指定形状,可实现降维。ravel()
:返回一个一维数组,可能是原数组的视图。flatten()
:返回一个一维数组,是原数组的副本。shape
属性:可直接修改数组的形状。
4. 数组元素的选取与修改
4.1 一维数组元素的选取与修改
import numpy as np
array1 = np.arange(1,9,1)
print(array1)
# 选取某个元素
a = array1[1]
# 选取某些元素
b = array1[[1,3,5]]
# 切片(左闭右开)
c = array1[0:6]
print(a, b, c)
# 修改某个元素
print(array1)
array1[0] = 10
print(array1)
# 批量修改某些元素
array1[[1,3,5]] = 20
print(array1)
array1[0:6] = 100
print(array1)
运行结果:先打印一维数组 array1
,然后打印选取的单个元素 a
、多个元素 b
和切片 c
,接着依次打印修改单个元素、多个元素和切片后的数组 array1
。
函数解析:
- 索引
[]
:用于选取数组中的单个元素或多个元素。 - 切片
[start:stop]
:用于选取数组中的一段元素,左闭右开区间。
4.2 二维数组元素的选取与修改
import numpy as np
array1 = np.arange(24).reshape(4,6)
print(array1)
# 选取某个元素
a = array1[1,4]
# 选取某行元素
b = array1[3,:]
# 选取某些行
c = array1[0:2,:]
d = array1[[0,2],:]
# 选取某列
e = array1[:,3]
# 选取某些列
f = array1[:,0:3]
g = array1[:,[0,3]]
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
print(g)
# 修改元素
# 修改某个元素
array1[1,4] = 100
print(array1)
# 修改某行元素
array1[3,:] = 100
print(array1)
array1[[0,2],:] = 50
print(array1)
运行结果:先打印二维数组 array1
,然后依次打印选取的单个元素 a
、某行元素 b
、某些行 c
、d
、某列元素 e
、某些列 f
、g
,接着依次打印修改单个元素、某行元素和某些行元素后的数组 array1
。
函数解析:
- 二维索引
[row, col]
:用于选取二维数组中的单个元素。 :
用于表示选取整行或整列。- 可以使用切片或列表来选取多行或多列。
4.3 三维数组元素的选取与修改
import numpy as np
array1 = np.arange(48).reshape(2,4,6)
print(array1)
# 选取某个元素
a = array1[1,0,0]
# 选取某行元素
b = array1[0,1,:]
# 选取某些行元素
c = array1[0,1:3,:]
d = array1[0,[1,3],:]
# 选取某列
e = array1[1,:,1]
# 选取某些列
f = array1[1,:,1:4]
g = array1[1,:,[1,4]]
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
print(g)
# 修改
array1[1,0,0] = 100
print(array1)
# 选取第三个三维数组的 第二个二维数组的 第三行以及之后的所有行的 第二列到第三列
v = np.array([array1,array1,array1,array1])
h = v[2,1,2: ,1:3]
print(h)
运行结果:先打印三维数组 array1
,然后依次打印选取的单个元素 a
、某行元素 b
、某些行元素 c
、d
、某列元素 e
、某些列元素 f
、g
,接着打印修改单个元素后的数组 array1
,最后打印复杂选取的结果 h
。
函数解析:三维数组的选取和修改与二维数组类似,只是多了一个维度的索引。
5. 数组的组合与切割
5.1 数组的组合
import numpy as np
# 生成基数组
array1 = np.arange(9).reshape(3,3)
array2 = 2*array1
print(array1)
print(array2)
# 水平组合
a3 = np.hstack((array1,array2))
a4 = np.hstack((array2,array1))
a5 = np.hstack((array1,array2,array1))
a6 = np.concatenate((array1,array2),axis=0)
# 连接#axis 表示连接的方向
# 垂直组合
a7 = np.vstack((array2,array1))
a8 = np.concatenate((array1,array2),axis=0)
print(a3)
print(a4)
print(a5)
print(a6)
print(a7)
print(a8)
运行结果:先打印基数组 array1
和 array2
,然后依次打印水平组合后的数组 a3
、a4
、a5
,垂直组合后的数组 a7
,以及使用 concatenate()
连接后的数组 a6
、a8
。
函数解析:
np.hstack()
:水平组合数组。np.vstack()
:垂直组合数组。np.concatenate()
:可以指定axis
参数来决定按行(axis=0
)或按列(axis=1
)连接数组。
5.2 数组的切割
import numpy as np
array1 = np.arange(16).reshape(4,4)
print(array1)
# 水平切割
a = np.hsplit(array1,2)
b = np.split(array1,2,axis=1)
# 垂直切割
c = np.vsplit(array1,2)
d = np.split(array1,2,axis=0)
# 强制切割
# 水平切割
e = np.array_split(array1,3,axis=1)
# 垂直切割
f = np.array_split(array1,3,axis=0)
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
print("#####################################")
array1 = np.arange(25).reshape(5,5)
print(array1)
g = np.array_split(array1,3,axis=1)
h = np.array_split(array1,3,axis=0)
print(g)
print(h)
运行结果:先打印 4x4 的数组 array1
,然后依次打印水平切割、垂直切割和强制切割后的结果,接着打印 5x5 的数组 array1
及其切割结果。
函数解析:
np.hsplit()
:水平切割数组。np.vsplit()
:垂直切割数组。np.split()
:可以指定axis
参数来决定按行(axis=0
)或按列(axis=1
)切割数组。np.array_split()
:可以进行非等分的切割。
6. 数组的算术运算与矩阵运算
6.1 数组的算术运算
import numpy as np
array1 = np.arange(1,5,1).reshape(2,2)
array2 = 2*array1
print(array1)
print(array2)
# 数组的加法【对应位置的元素求和】
print(array1 + array2)
# 数组的减法[对应位置元素相减]
print(array1 - array2)
# 数组的乘法【对应位置相乘】
print(array1 * array2)
# 数组的除法[对应位置相除]
print(array1 / array2)
# 数组的取余(%)
print(array2 % array1)
# 数组的取整
print(array2 // array1)
运行结果:先打印数组 array1
和 array2
,然后依次打印它们的加法、减法、乘法、除法、取余和取整结果。
函数解析:NumPy 数组的算术运算都是对应元素之间的运算。
6.2 矩阵运算
import numpy as np
# 生成两个基数组
a = np.arange(4).reshape(2,2)
b = a.copy()
print(a)
print(b)
# 矩阵的运算
# 加减乘除(求逆)
# 加减 -> 对应元素加减
# 矩阵的乘法【点乘】
# a * b
a1 = a.dot(b)
a2 = np.dot(a, b)
print(a1)
print(a2)
# 矩阵求逆
"""
inv():
并不是所有的矩阵都有逆;
即使你没有逆,给你一个逆【伪逆】
"""
a3 = np.linalg.inv(a)
print(a3)
a4 = a.dot([[-1.5, 0.5],
[ 1., 0. ]])
print(a4)
运行结果:先打印基数组 a
和 b
,然后打印矩阵乘法结果 a1
、a2
,矩阵求逆结果 a3
,以及矩阵与另一个矩阵相乘的结果 a4
。
函数解析:
dot()
或np.dot()
:用于矩阵乘法。np.linalg.inv()
:用于求矩阵的逆。
7. NumPy 内的随机模块
7.1 生成随机整数
import numpy as np
import matplotlib.pyplot as plt
# 设置随机种子,确保结果可复现
np.random.seed(1000)
# 生成单个随机整数(0 - 9 之间)
r1 = np.random.randint(0, 10)
print(f"生成的随机整数是: {r1}")
# 生成 100 个随机整数并统计分布
a = [np.random.randint(0, 10) for i in range(100)]
print(a)
# 绘制直方图
plt.hist(a, color='r')
plt.show()
运行结果:打印生成的单个随机整数 r1
和 100 个随机整数列表 a
,并显示随机整数分布的直方图。
函数解析:
np.random.seed()
:设置随机种子,确保每次运行代码生成的随机数相同。np.random.randint()
:生成指定范围内的随机整数。
7.2 生成随机浮点数和特定分布的随机数
import numpy as np
# 设置随机种子
np.random.seed(1000)
# 生成 0 - 1 之间的随机浮点数
random_float = np.random.rand()
print(f"生成的随机浮点数是: {random_float}")
"""
normal()->生成一些符合正态分布的数据
N~(日,1)
numpy.random.normal(loc=0.0,scale=1.0,size=None)
参数说明:
Loc:正态分布的均值(期望值),决定了分布的中心位置,默认值为 0.0
scale:正态分布的标准差,决定了分布的离散程度,默认值为 1.0
size:输出数组的形状,可以是整数(表示一维数组长度)或元组(表示多维数组形状),默认值为 None(返回单个值)
"""
# 生成正态分布随机数(均值 0,标准差 1)
normal_random = np.random.normal(loc=0, scale=1)
print(f"生成的正态分布随机数是: {normal_random}")
# 生成 5x5 的随机整数数组(0 - 9 之间)
random_array = np.random.randint(0, 10, size=(5, 5))
print("生成的 5x5 随机整数数组:")
print(random_array)
# 生成指定形状的均匀分布随机数组
uniform_array = np.random.rand(3, 4)
print("\n生成的 3x4 均匀分布随机数组:")
print(uniform_array)
# 生成指定形状的正态分布随机数组
normal_array = np.random.normal(loc=5, scale=2, size=(2, 3))
print("\n生成的 2x3 正态分布随机数组(均值 5,标准差 2):")
print(normal_array)
运行结果:依次打印生成的随机浮点数、正态分布随机数、5x5 随机整数数组、3x4 均匀分布随机数组和 2x3 正态分布随机数组。
函数解析:
np.random.rand()
:生成 0 - 1 之间的随机浮点数。np.random.normal()
:生成符合正态分布的随机数。np.random.randint()
:可以指定size
参数生成多维随机整数数组。
8. 数组的深拷贝与浅拷贝
import numpy as np
array1 = np.array([1,2,3])
# 浅拷贝
array2 = array1
# 更改 array2 的元素的值
array2[0] = 100
print(array2)
print(array1)
print("###################")
# 深拷贝
array3 = array1.copy()
array3[0] = 10
print(array3)
print(array1)
运行结果:先打印浅拷贝后修改 array2
元素值时 array2
和 array1
的值,再打印深拷贝后修改 array3
元素值时 array3
和 array1
的值。
函数解析:
- 浅拷贝:
array2 = array1
只是创建了一个指向同一数组的新引用,修改array2
会影响array1
。 - 深拷贝:
array3 = array1.copy()
创建了一个独立的数组副本,修改array3
不会影响array1
。
9. NumPy 内一些函数的使用
import numpy as np
array1 = np.random.normal(size = (3,3))
print(array1)
# 一些函数
# 求方差
print(array1.var())
# 求标准差
a = array1.std()
# 求均值
b = array1.mean()
# 求和
c = array1.sum()
# 求中位数
d = np.median(array1)
# 求和运算
# 对矩阵的行求和
e = array1.sum(axis=1)
# 对矩阵的列进行求和
f = array1.sum(axis=0)
print(a)
print(b)
print(c)
print(d)
print(e)
print(f)
运行结果:先打印随机生成的 3x3 数组 array1
,然后依次打印数组的方差、标准差、均值、总和、中位数,以及按行和按列求和的结果。
函数解析:
var()
:计算数组的方差。std()
:计算数组的标准差。mean()
:计算数组的均值。sum()
:计算数组的总和,可指定axis
参数按行或按列求和。np.median()
:计算数组的中位数。
10. 读取和保存文件
# numpy.loadtxt(): 从文本文件中加载数据。这个函数假定文件中的每一行都有相同数量的值,
# 你可以使用 delimiter 参数指定分隔符,如逗号、制表符等。例如:
import numpy as np
data = np.loadtxt('a.txt', delimiter='\t')
print(data)
# 将数组保存到 txt 文件中
import numpy as np
array = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
np.savetxt('b.txt', array)
运行结果:从 a.txt
文件中读取数据并打印,然后将一个 3x3 数组保存到 b.txt
文件中。
函数解析:
np.loadtxt()
:从文本文件中加载数据,可指定分隔符。np.savetxt()
:将数组保存到文本文件中。