Python的三方库之NumPy(一)
这要求维数相同,且各维度的长度相同,如果不相同,可以通过广播机制,这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。这个盒子可以是平的(一维数组),也可以是立体的(多维数组),比如一个表格(二维数组)或者一个立方体(三维数组)。2 、在 NumPy 中,计算方差var()时使用的是统计学中的方差公式,而不是概率论中的方差公式,主要是因为 Num
Python的三方库之NumPy(一)
文章目录
一、NumPy 基础入门
如何安装 NumPy
安装 NumPy 很简单,只需要在命令行中输入以下命令:
pip install numpy==1.26.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/
如果你在安装过程中遇到问题,可能是因为网络原因或者链接有问题。可以尝试检查链接的合法性,或者稍后再试。
二、ndarray:NumPy 的核心
NumPy 的核心是一个叫 ndarray
的东西,它是一个用来存储相同类型数据的数组。你可以把它想象成一个盒子,里面装的都是同一种东西,比如全是苹果或者全是橙子。这个盒子可以是平的(一维数组),也可以是立体的(多维数组),比如一个表格(二维数组)或者一个立方体(三维数组)。
ndarray
的每个元素在内存里都占同样的空间,就像整齐排列的小盒子一样。你可以通过索引(比如 array[0]
)或者切片(比如 array[1:3]
)来找到里面的元素。
它的主要特点有:
- 多维数组:可以是一维、二维、三维,甚至更高维度。
- 同质数据类型:数组里的所有元素必须是同一种类型,比如全是整数或者全是浮点数。
- 高效内存布局:数组在内存里是连续存储的,所以访问起来很快。
- 功能强大:提供了很多数学函数和操作,比如矩阵运算、线性代数、傅里叶变换等。
2.1 创建 ndarray
NumPy 提供了很多方法来创建 ndarray
,最常用的是 array()
函数。
创建 ndarray 的语法
numpy.array(object, dtype=None, copy=True, order=None, ndmin=0)
参数说明:
参数 | 描述 |
---|---|
object | 一个序列(比如列表、元组)或者嵌套的序列,用来创建数组。 |
dtype | 可选,指定数组的数据类型(比如 int 、float )。如果不指定,会自动推断。 |
copy | 可选,默认为 True ,表示是否复制输入对象。如果为 False ,则直接使用输入对象。 |
order | 内存布局方式,C 表示按行存储,F 表示按列存储,A 表示默认。 |
ndmin | 可选,指定数组的最小维度。比如 ndmin=2 表示至少是一个二维数组。 |
示例
import numpy as np
# array(): 创建一个数组
# object:数组的元素 可以不输入object
# dtype:数组元素的数据类型
# order:数组的存储顺序,C表示按行存储,F表示按列存储
# ndmin:数组的维度
a = np.array([1, 2, 3, 4, 5, 6],dtype=np.int64,order='F',ndmin=2)
print(a)
2.2 zeros()
zeros()
函数可以创建一个全是 0 的数组,形状由你指定。
格式
numpy.zeros(shape, dtype=float, order='C')
参数说明:
参数 | 描述 |
---|---|
shape | 数组的形状,比如 (2, 3) 表示 2 行 3 列。 |
dtype | 可选,指定数组的数据类型,默认是 float 。 |
order | 内存布局方式,C 表示按行存储,F 表示按列存储。 |
示例
# zeros(): 创建一个全为浮点数0.0的数组
a = np.zeros((2,3))
print(a)
2.3 ones()
ones()
函数可以创建一个全是 1 的数组,形状由你指定。
格式
numpy.ones(shape, dtype=None, order='C')
参数说明:
参数 | 描述 |
---|---|
shape | 数组的形状,比如 (2, 3) 表示 2 行 3 列。 |
dtype | 可选,指定数组的数据类型。如果不指定,会根据上下文推断。 |
order | 内存布局方式,C 表示按行存储,F 表示按列存储。 |
示例
# ones(): 创建一个全为浮点数1.0的数组
a = np.ones((2,3))
print(a)
2.4 full()
full()
函数可以创建一个填充指定值的数组。
格式
numpy.full(shape, fill_value, dtype=None, order='C')
参数说明:
参数 | 描述 |
---|---|
shape | 数组的形状,比如 (2, 3) 表示 2 行 3 列。 |
fill_value | 填充的值,比如 5 或者 3.14 。 |
dtype | 可选,指定数组的数据类型。如果不指定,会根据 fill_value 推断。 |
order | 内存布局方式,C 表示按行存储,F 表示按列存储。 |
示例
# full(): 创建一个数组,元素全部填充值为后面的数字
a = np.full((2,3),4)
print(a)
2.5 arange()
arange()
函数可以创建一个等差数列的数组,有点像 Python 的 range()
,但返回的是 NumPy 数组。
格式
numpy.arange(start, stop, step, dtype)
参数说明:
参数 | 描述 |
---|---|
start | 起始值,默认为 0。 |
stop | 终止值(不包含),比如 stop=5 表示生成的数组不会包含 5。 |
step | 步长,默认为 1。 |
dtype | 可选,指定数组的数据类型。如果不指定,会根据输入数据推断。 |
示例
# arange(start,stop,step): 创建一个等差数列的数组(不包括stop)
a = np.arange(1,10,2)
print(a) # [1 3 5 7 9]
2.6 linspace:生成均匀间隔的数组
linspace
是一个非常实用的函数,它可以在指定的数值区间内生成均匀间隔的数字。比如你想在 1 到 10 之间平均分成 10 份,linspace
就能轻松做到。
格式
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数说明
参数 | 描述 |
---|---|
start | 起始值,比如从哪里开始,就像数数从 1 开始。 |
stop | 终止值,也就是结束的地方,默认是包含在内的,比如数到 10。 |
num | 要生成多少个均匀的数字,默认是 50 个。比如你想分成 10 份,就写 num=10 。 |
endpoint | 默认为 True ,表示包含终止值。如果设为 False ,那么终止值就不会被包含。 |
retstep | 是否返回步长(也就是每两个数字之间的间隔)。如果设为 True ,会返回一个包含数组和步长的元组;如果设为 False ,就只返回数组。默认是 False 。 |
dtype | 数组的数据类型,比如是整数还是浮点数。如果不指定,会自动根据输入推断。 |
示例
import numpy as np
# 在 0 到 10 之间生成 5 个均匀间隔的数字
arr = np.linspace(0, 10, num=5)
print(arr) # 输出:[ 0. 2.5 5. 7.5 10. ]
# 不包含终止值 10
arr_no_end = np.linspace(0, 10, num=5, endpoint=False)
print(arr_no_end) # 输出:[ 0. 2. 4. 6. 8.]
# 返回步长
arr_with_step = np.linspace(0, 10, num=5, retstep=True)
print(arr_with_step) # 输出:(array([ 0., 2.5, 5., 7.5, 10.]), 2.5)
通俗解释
start
和stop
:就像在一条直线上,start
是起点,stop
是终点。num
:你想把这段距离分成多少份。比如从 0 到 10,分成 5 份,每份就是 2.5。endpoint
:如果设为False
,终点就不会被包含进去。比如从 0 到 10,分成 5 份,但不包含 10,那么就是[0, 2, 4, 6, 8]
。retstep
:如果你想知道自己生成的数组每两个数字之间的间隔是多少,可以设为True
,它会告诉你。
三、数据类型
NumPy 提供了比 Python 更加丰富的数据类型,如下所示:
序号 | 数据类型 | 语言描述 |
---|---|---|
1 | bool_ | 布尔型数据类型(True 或者 False) |
2 | int_ | 默认整数类型,类似于 C 语言中的 long,取值为 int32 或 int64 |
3 | intc | 和 C 语言的 int 类型一样,一般是 int32 或 int 64 |
4 | intp | 用于索引的整数类型(类似于 C 的 ssize_t,通常为 int32 或 int64) |
5 | int8 | 代表与1字节相同的8位整数。值的范围是-128到127 |
6 | int16 | 代表 2 字节(16位)的整数。范围是-32768至32767 |
7 | int32 | 代表 4 字节(32位)整数。范围是-2147483648至2147483647 |
8 | int64 | 表示 8 字节(64位)整数。范围是-9223372036854775808至9223372036854775807 |
9 | uint8 | 1字节(8位)无符号整数 |
10 | uint16 | 2 字节(16位)无符号整数 |
11 | uint32 | 4 字节(32位)无符号整数 |
12 | uint64 | 8 字节(64位)无符号整数 |
13 | float_ | float64 类型的简写 |
14 | float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10个尾数位 |
15 | float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23个尾数位 |
16 | float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52个尾数位 |
17 | complex_ | 复数类型,与 complex128 类型相同 |
18 | complex64 | 表示实部和虚部共享 32 位的复数 |
19 | complex128 | 表示实部和虚部共享 64 位的复数 |
20 | str_ | 表示字符串类型,等价于unicode_ |
21 | bytes_ | 表示字节串类型,基于字节 |
22 | string_ | 表示字节串类型,等价于bytes_ ,基于字节,NumPy 2.0以后版本被移除,使用bytes_ 代替 |
23 | unicode_ | 表示字节串类型,基于字符,NumPy 2.0以后版本被移除,使用str_`代替 |
四、数组属性:了解 NumPy 数组的“身份证”
4.1 shape函数
shape
是一个非常重要的属性,它告诉我们数组的“身材”——也就是数组在每个维度上的大小。比如,一个二维数组有几行几列,shape
就会返回一个元组,比如 (2, 3)
,表示这个数组有 2 行、3 列。
功能
- 查看数组的维度大小:
shape
会返回一个元组,元组的长度就是数组的维度数。比如,(2, 3)
表示二维数组,(2, 3, 4)
表示三维数组。 - 调整数组的形状:通过给
shape
赋值,可以直接改变数组的形状。不过要注意,改变形状时,数组的总元素数量不能变。
重点
- 如果用
shape
修改数组形状,会直接改变原数组的形状。 - 如果想保留原数组不变,可以用
reshape
方法,它会返回一个新数组,原数组不会变。
4.2 数组维度
数组的维度就是数组的“层数”。简单来说,就是用几个数字才能唯一确定数组中的一个元素。比如:
- 一维数组(列表):只需要一个数字确定位置,比如
[1, 2, 3]
。 - 二维数组(表格):需要两个数字确定位置,比如
[[1, 2], [3, 4]]
。 - 三维数组(立方体):需要三个数字确定位置。
相关概念
ndmin
参数:在创建数组时,可以用ndmin
参数指定数组的最小维度。比如,ndmin=2
表示至少是一个二维数组,哪怕你传入的是一维数据,它也会变成二维形式。ndim
属性:用来查看数组的维度数。比如,二维数组的ndim
是 2,三维数组的ndim
是 3。
4.3 flags函数
flags
属性告诉我们数组在内存中的存储情况,就像数组的“身份证”。它包含以下信息:
C_CONTIGUOUS
:表示数组是否按 C 风格(按行存储)连续存储。F_CONTIGUOUS
:表示数组是否按 Fortran 风格(按列存储)连续存储。OWNDATA
:表示数组是否拥有自己的数据,还是引用了其他数组的数据。WRITEABLE
:表示数组是否可以被修改(写入)。ALIGNED
:表示数组是否按照内存对齐的方式存储。WRITEBACKIFCOPY
:表示数组是否是另一个数组的副本,修改后是否需要写回原数组。
案例
# shape
a = np.array([1, 2, 3, 4, 5, 6])
a.shape = (2, 3)
print(a)
"""
[[1 2 3]
[4 5 6]]
"""
# ndim返回维度
print(a.ndim) # 2
# flags:返回数组的各种属性
print(a.flags)
# C_CONTIGUOUS : True
# F_CONTIGUOUS : False
# OWNDATA : True
# WRITEABLE : True
# ALIGNED : True
# WRITEBACKIFCOPY : False
五、切片:轻松提取数组片段
切片是 NumPy 中非常强大的功能,它可以帮助我们从数组中提取出我们需要的部分,就像切蛋糕一样。切片操作和 Python 中的列表切片很相似。
5.1 切片的基本概念
切片可以通过 [start:stop:step]
的形式来实现,它的参数含义如下:
start
:切片开始的位置(包含该位置)。stop
:切片结束的位置(不包含该位置)。step
:切片的步长,即每隔多少个元素取一个。
切片的作用
- 提取范围:可以用冒号
:
来表示一个范围。比如array[1:3]
表示从索引 1 到索引 3(不包括 3)的元素。 - 提取所有元素:单独使用冒号
:
表示提取所有元素。比如array[:, 1]
表示提取所有行的第 1 列。 - 设置步长:在双冒号后面加上步长值,比如
array[::2]
表示每隔一个元素取一个。
特殊符号的作用
- 冒号
:
:对于一维数组,按索引号截取;对于二维数组,按行和列截取。 - 省略号
...
:表示所有维度,可以简化多维数组的切片操作。比如array[..., 1]
表示取所有行的第 1 列。
5.2 切片的注意事项
- 返回视图:切片返回的数组是原数组的一个“视图”,而不是一个独立的副本。这意味着如果你修改了切片返回的数组,原数组中的数据也会被修改。
- 灵活使用:切片操作非常灵活,可以用于一维数组、二维数组,甚至更高维的数组。
5.3 切片的常见用法
- 提取某一行或某一列:比如
array[1, :]
表示提取第 2 行的所有元素,array[:, 1]
表示提取所有行的第 2 列。 - 提取特定范围:比如
array[1:3, 1:3]
表示提取第 2 行到第 3 行、第 2 列到第 3 列的元素。 - 使用步长:比如
array[::2]
表示每隔一个元素取一个,array[1::2]
表示从第 2 个元素开始每隔一个取一个。
案例
import numpy as np
# 切片,slice():[start:stop:step](不包含stop)
# numpy二维数组切片分成行方向和列方向
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
# 获取第一列数据
print(a[:,0])
print(a[...,0]) # 等价于a[:,0],...表示保留
# 获取第二行数据
print(a[1,:])
# 获取第二三行第二三列数据
print(a[1:3,1:3])
# 获取第二三行第二三列数据,但只获取第一列数据
print(a[1:3,1:3][:,0])
六、高级索引
6.1 整数数组索引
整数数组索引是指使用一个数组来访问另一个数组的元素。这个数组中的每个元素都是目标数组中某个维度上的索引值。
适用于需要访问非连续元素或特定位置元素的场景。
注意:返回的新数组是一个副本,修改它不会影响原数组。
案例:
# 整数数组索引 主要用来访问特定值
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[[0,1,2],[0,1,0]]) # [1 5 7]
# 取出4×3矩阵四个角的数据
a = np.arange(12).reshape(4,3)
print(a)
print(a[[0,0,-1,-1],[0,-1,0,-1]]) #[ 0 2 9 11]
6.2 布尔索引
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
案例:
import numpy as np
# 一维数组
arr = np.array([1, 2, 3, 4, 5])
print(arr[arr > 2])
# 二维数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr[arr > 2])
# 使用布尔索引值取值
bool_arr = arr > 2
print(bool_arr) #[[False False True] [ True True True]]
# 切片布尔索引
arr = np.array([[1, 2, 3], [4, 5, 6],[7, 8, 9]])
print(arr[arr[:,2] > 5]) #索引大于5的行
''' 输出结果
[[4 5 6]
[7 8 9]]
'''
print(arr[: ,arr[1]> 5]) # 索引大于5的列
'''
(:) 表示选择数组的所有行。
arr[1] > 5 是布尔数组 [False, False, True],表示选择第 3 列(索引为 2 的列)。
因此,arr[:, arr[1] > 5] 的结果是选择所有行的第 3 列:
输出结果
[[3]
[6]
[9]]
'''
七、广播(*)
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。这要求维数相同,且各维度的长度相同,如果不相同,可以通过广播机制,这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。
前提:在行或者列的维度为1,才能使用广播机制
案例:
# 前提:在行或者列的维度为1,才能使用广播机制
# 维度匹配
a = np.array([[1,2,3],[4,5,6]])
b = np.array([10,20,30]) # 自动广播成([[10,20,30],[10,20,30]])
c = a + b
print(c) # [[11 22 33] [14 25 36]]
# 形状匹配:两个数组在某个维度的长度不同,但是其中有一个数组在该维度的长度为1,则数组会沿着该维度进行广播
a = np.array([[1],[2]]) # a.shape = (2,1)
b = np.array([10,20,30]) # b.shape = (3,)
c = a + b
print(c) # [[11 21 31] [12 22 32]]
# 不匹配,则广播失败,抛出valueerror
# 一维数组与标量相加
a = np.array([1,2,3])
a = a + 10
print(a) # [11 12 13]
# 矩阵与标量相加
a = np.array([[1,2,3],[4,5,6]])
a = a + 10
print(a) # [[11 12 13] [14 15 16]]
# 矩阵与矩阵相加,形状必须匹配,或者某个维度的长度为1
a = np.array([[1,2,3],[4,5,6]])
b = np.array([[10,20,30],[40,50,60]])
c = a + b
print(c) # [[11 22 33] [44 55 66]]
八、遍历数组
8.1 遍历数组的第一维度
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
for i in arr:
print(i)
for i in arr:
遍历数组的第一维度,即按行或列的顺序逐个访问元素。
返回的是数组的子数组(如行或列),而不是单个元素。
8.2 nditer逐个访问元素
nditer 是 NumPy 中的一个强大的迭代器对象,用于高效地遍历多维数组。nditer 提供了多种选项和控制参数,使得数组的迭代更加灵活和高效。
控制参数
nditer 提供了多种控制参数,用于控制迭代的行为。
1.order 参数
order 参数用于指定数组的遍历顺序。默认情况下,nditer 按照 C 风格(行优先)遍历数组。
- C 风格(行优先): order=‘C’
- Fortran 风格(列优先): order=‘F’
案例
import numpy as np
# 二维数组用for循环遍历
a = np.arange(6).reshape(2, 3)
for i in a:
print(i,end=' ')
for j in i:
print(j,end=' ') # 输出结果为:0 1 2 3 4 5
print()
# 二维数组用np.nditer遍历
# 控制参数
# order='C'表示按C语言的顺序遍历,按行遍历(默认)
# order='F'表示按Fortran的顺序遍历,按列遍历
for i in np.nditer(a):
print(i,end=' ') # 输出结果为:0 1 2 3 4 5
print()
for i in np.nditer(a,order='F'):
print(i,end=' ') # 输出结果为:0 1 2 3 4 5
print()
# flags: 控制遍历的参数
# 参数值:
# multi_index:表示遍历过程中,是否显示索引值
# external_loop:表示遍历过程中,是否显示外层索引值
# 默认为:multi_index=False,external_loop=False
a = np.arange(6).reshape(2, 3)
it_1 = np.nditer(a,flags=['multi_index'])
for i in it_1:
print(i,it_1.multi_index)
""""运行结果为:
0 (0, 0)
1 (0, 1)
2 (0, 2)
3 (1, 0)
4 (1, 1)
5 (1, 2)
"""
it_2 = np.nditer(a,flags=['external_loop'])
for i in it_2:
print(i) # [0 1 2 3 4 5]
九、数组操作
9.1 数组变维
函数名称 | 函数介绍 |
---|---|
reshape | 在不改变数组元素的条件下,修改数组的形状 |
flat属性 | 返回是一个迭代器,可以用 for 循环遍历其中的每一个元素 |
flatten | 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组 |
ravel | 返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组) |
9.1.1 reshape
reshape: 重新调整数组的形状
前提:输入的数组的元素个数必须与原数组的元素个数相同
是原数组的视图,修改数据原本数据也会改变
案例
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)
print(arr.shape)
newarr = arr.reshape(3, 2)
print(newarr)
print(newarr.shape)
newarr[0,0]=100 # 原数组arr的数据也会修改
print(arr)
print(newarr)
# -1 表示自动计算
new_arr = arr.reshape((3, -1))
print(new_arr)
a = np.arange(1,10).reshape(3,3)
print(a)
9.1.2 flat、flatten、ravel方法
- flat属性:返回一个一维数组迭代器,可以用循环遍历数组中的元素。
a = np.arange(1,10).reshape(3,3)
for i in a.flat:
print(i,end=' ') # 1 2 3 4 5 6 7 8 9
print()
- flatten方法:返回一个一维数组,是原数组的副本,修改新数据时原数据不会影响。
a = np.arange(1,10).reshape(3,3)
b = a.flatten()
print(b) # [1 2 3 4 5 6 7 8 9]
b[0] = 100
print(b) # [100 2 3 4 5 6 7 8 9]
print(a)
# [[ 1 2 3]
# [ 4 5 6]
# [ 7 8 9]]
- ravel方法:返回一个一维数组,是原数组的视图,修改数据原本数据也会改变。
a = np.arange(1,10).reshape(3,3)
b = a.ravel()
print(b) # [1 2 3 4 5 6 7 8 9]
b[0] = 100
print(b) # [100 2 3 4 5 6 7 8 9]
print(a)
# [[100 2 3]
# [ 4 5 6]
# [ 7 8 9]]
9.2 数组转置
函数名称 | 说明 |
---|---|
transpose | 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2) |
ndarray.T | 与 transpose 方法相同 |
案例
import numpy as np
arr = np.arange(9).reshape(3,3)
print(arr)
print(arr.transpose())
print(arr.T)
输出结果:
[[0 1 2]
[3 4 5]
[6 7 8]]
[[0 3 6]
[1 4 7]
[2 5 8]]
[[0 3 6]
[1 4 7]
[2 5 8]]
9.3 升维和降维
多维数组(也称为 ndarray)的维度(或轴)是从外向内编号的。这意味着最外层的维度是轴0,然后是轴1,依此类推。
函数名称 | 参数 | 说明 |
---|---|---|
expand_dims(arr, axis) | arr:输入数组 axis:新轴插入的位置 |
在指定位置插入新的轴(相对于结果数组而言),从而扩展数组的维度 |
squeeze(arr, axis) | arr:输入数的组 axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项 |
删除数组中维度为 1 的项 |
升维案例
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(np.expand_dims(arr, axis=0)) # [[1 2 3 4 5]]
print(np.expand_dims(arr, axis=1))
# [[1]
# [2]
# [3]
# [4]
# [5]]
降维案例
# squeeze(arr,axis)
arr = np.array([[[1, 2, 3]]])
print(arr)
print(arr.shape) # (1, 2, 3)
# 最外层降维
a = np.squeeze(arr, axis=0)
print(a)
print(a.shape) # (1, 3)
# 第二层降维
b = np.squeeze(arr, axis=1)
print(b)
print(b.shape)
9.4 连接和分割数组
函数名称 | 参数 | 说明 |
---|---|---|
hstack(tup) | tup:可以是元组,列表,或者numpy数组,返回结果为numpy的数组 | 按水平顺序堆叠序列中数组(列方向) |
vstack(tup) | tup:可以是元组,列表,或者numpy数组,返回结果为numpy的数组 | 按垂直方向堆叠序列中数组(行方向) |
hsplit(ary, indices_or_sections) | ary:原数组 indices_or_sections:按列分割的索引位置 |
将一个数组水平分割为多个子数组(按列) |
vsplit(ary, indices_or_sections) | ary:原数组 indices_or_sections:按行分割的索引位置 |
将一个数组垂直分割为多个子数组(按行) |
连接数组案例
# hstack():水平方向连接数组
# vstack():竖直方向连接数组
import numpy as np
a = np.arange(0, 10).reshape(2, 5)
b = np.arange(10, 20).reshape(2, 5)
print(np.hstack((a, b)))
print()
print(np.vstack((a, b)))
[[ 0 1 2 3 4 10 11 12 13 14]
[ 5 6 7 8 9 15 16 17 18 19]]
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
分割数组案例
# hsplit(ary,indices_or_sections): 按列分割(水平方向分割)
# vsplit(ary,indices_or_sections): 按行分割(垂直方向分割)
a = np.arange(16).reshape(4,4)
print(a)
b = np.hsplit(a,2)
print(b)
c = np.vsplit(a,2)
print(c)
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
[array([[ 0, 1],
[ 4, 5],
[ 8, 9],
[12, 13]]), array([[ 2, 3],
[ 6, 7],
[10, 11],
[14, 15]])]
[array([[0, 1, 2, 3],
[4, 5, 6, 7]]), array([[ 8, 9, 10, 11],
[12, 13, 14, 15]])]
9.5 矩阵运算
1、np.dot
是一个通用的点积函数,适用于多种维度的数组。
- 对于二维数组(矩阵),
np.dot
等价于矩阵乘法。 - 对于一维数组(向量),
np.dot
计算的是向量的点积(内积)。
import numpy as np
# 矩阵运算
# np.dot(a,b): 矩阵乘法,点积函数
# 矩阵运算
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
c = np.dot(a,b)
print(c)
# np.matmul
# 是专门用于矩阵乘法的函数,适用于二维及更高维度的数组。
c = np.matmul(a,b)
print(c)
# 向量运算
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.dot(a,b)
print(c)
[[19 22]
[43 50]]
[[19 22]
[43 50]]
32
2、np.linalg.det
计算一个方阵(行数和列数相等的矩阵)的行列式。
# np.linalg.det
# 计算矩阵的行列式值。(n×n的方阵)
a = np.array([[1,2],[3,4]])
print(np.linalg.det(a)) # 输出:-2.0000000000000004
十、数组元素增删查改
10.1 resize
函数名称 | 参数 | 说明 |
---|---|---|
resize(a, new_shape) | a:操作的数组 new_shape:返回的数组的形状,如果元素数量不够,重复数组元素来填充新的形状 |
返回指定形状的新数组 |
案例:
# 元素数量不够会重复数组元素来填充
a = np.arange(0,6).reshape(2,3)
b = np.resize(a,(3,3))
print(b)
# [[0 1 2]
# [3 4 5]
# [0 1 2]]
10.2 append
函数名称 | 参数 | 说明 |
---|---|---|
append(arr, values, axis=None) | arr:输入的数组 values:向 arr 数组中添加的值,需要和 arr 数组的形状保持一致 axis:默认为 None,返回的是一维数组;当 axis =0 时,追加的值会被添加到行,而列数保持不变,若 axis=1 则与其恰好相反 |
在数组的末尾添加值,返回一个一维数组 |
案例:
# append
# axis=0 在行上添加,axis=1 在列上添加,axis = None返回一个一维数组
a = np.arange(0,6).reshape(2,3)
b = np.append(a,[[7,8,9]],axis=0)
print(b)
# [[0 1 2]
# [3 4 5]
# [7 8 9]]
c = np.append(a,[[7,7],[8,8]],axis=1)
print(c)
# [[0 1 2 7 7]
# [3 4 5 8 8]]
d = np.append(a,[[7,8,9]],axis=None)
print(d)
# [0 1 2 3 4 5 7 8 9]
10.3 insert
函数名称 | 参数 | 说明 |
---|---|---|
insert(arr, obj, values, axis) | arr:输入的数组 obj:表示索引值,在该索引值之前插入 values 值 values:要插入的值 axis:默认为 None,返回的是一维数组;当 axis =0 时,追加的值会被添加到行,而列数保持不变,若 axis=1 则与其恰好相反 |
沿规定的轴将元素值插入到指定的元素前 |
案例:
# insert(arr,obj,value,axis): 在指定轴上添加元素
# axis=0 在行上添加,axis=1 在列上添加,axis = None返回一个一维数组
a = np.arange(0,6).reshape(2,3)
b = np.insert(a,1,[7,8,9],axis=0)
print(b)
# [[0 1 2]
# [7 8 9]
# [3 4 5]]
c = np.insert(a,1,[7,8],axis=1)
print(c)
# [[0 7 1 2]
# [3 8 4 5]]
d = np.insert(a,1,[7,8],axis=None)
print(d)
# [0 7 8 1 2 3 4 5]
e = np.insert(a,1,[100],axis = 0) # 自动广播
print(e)
# [[ 0 1 2]
# [100 100 100]
# [ 3 4 5]]
10.4 delete
函数名称 | 参数 | 说明 |
---|---|---|
delete(arr, obj, axis) | arr:输入的数组 obj:表示索引值,要删除数据的索引 axis:默认为 None,返回的是一维数组;当 axis =0 时,删除指定的行,若 axis=1 则与其恰好相反 |
删掉某个轴上的子数组,并返回删除后的新数组 |
案例:
# delete(arr,obj,axis)
# axis=0,删除行
# axis=1,删除列
# axis=None,删除之后返回一维数组
arr = np.arange(9).reshape(3,3)
a = np.delete(arr,1,axis=0)
print(a)
# [[0 1 2]
# [6 7 8]]
b = np.delete(arr,1,axis=1)
print(b)
# [[0 2]
# [3 5]
# [6 8]]
c = np.delete(arr,[0,1],axis=0) # 删除0,1行
print(c)
# [[6 7 8]]
d = np.delete(arr,1,axis=None)
print(d)
# [0 2 3 4 5 6 7 8]
10.5 argwhere
返回数组中非 0 元素的索引,若是多维数组则返回行、列索引组成的索引坐标
案例:
# argwhere 函数
# 输出为索引,默认返回非零元素的索引
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
print(np.argwhere(a))
# [[0 0]
# [0 1]
# [0 2]
# [1 0]
# [1 1]
# [1 2]]
print(np.argwhere(a>2))
# [[0 2]
# [1 0]
# [1 1]
# [1 2]]
10.6 unique
函数名称 | 参数 | 说明 |
---|---|---|
unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None) | ar:输入的数组 return_index:如果为 True,则返回新数组元素在原数组中的位置(索引) return_inverse:如果为 True,则返回原数组元素在新数组中的位置(逆索引) return_counts:如果为 True,则返回去重后的数组元素在原数组中出现的次数 |
删掉某个轴上的子数组,并返回删除后的新数组 |
案例1:返回唯一元素的索引
a = np.array([6,2,3,4,5,1,2,3,4,5])
print(np.unique(a,return_index=True))
# (array([1, 2, 3, 4, 5, 6]), array([5, 1, 2, 3, 4, 0], dtype=int64))
案例2:返回唯一元素及其逆索引
print(np.unique(a,return_inverse=True))
# (array([1, 2, 3, 4, 5, 6]), array([5, 1, 2, 3, 4, 0, 1, 2, 3, 4], dtype=int64))
案例3:返回唯一元素的计数
print(np.unique(a,return_counts=True))
# (array([1, 2, 3, 4, 5, 6]), array([1, 2, 2, 2, 2, 1], dtype=int64))
案例4:二维数组去重
# 二维数组去重
a = np.array([[1,2],[2,3],[3,1]])
print(np.unique(a))# [1 2 3]
十一、统计函数
11.1 amin() 和 amax()
- 计算数组沿指定轴的最小值与最大值,并以数组形式返回
- 对于二维数组来说,axis=1 表示沿着水平方向,axis=0 表示沿着垂直方向
# 一维数组
a = np.array([1, 2, 3, 4, 5])
print(np.amin(a))
print(np.amax(a))
# 二维数组
a = np.array([[1, 22, 3], [4, 52, 6]])
print(np.amin(a,axis=1)) #[1 4]
print(np.amax(a,axis=1)) #[22 52]
print(np.amin(a,axis=0)) #[1 22 3]
print(np.amax(a,axis=0)) #[4 52 6]
print(np.amin(a)) # 1
print(np.amax(a)) # 52
11.2 ptp()
- 计算数组元素中最值之差值,即最大值 - 最小值
- 对于二维数组来说,axis=1 表示沿着水平方向,axis=0 表示沿着垂直方向
a = np.array([[1, 22, 3], [4, 52, 6]])
print(np.ptp(a,axis=1)) # [21 48]
print(np.ptp(a,axis=0)) #[3 30 3]
print(np.ptp(a)) #51
11.3 median()
用于计算中位数,中位数是指将数组中的数据按从小到大的顺序排列后,位于中间位置的值。如果数组的长度是偶数,则中位数是中间两个数的平均值。
# median(): 中位数
a = np.array([[1, 2, 3], [4, 5, 6]])
print(np.median(a)) # 3.5
print(np.median(a, axis=0)) # [2.5 3.5 4.5]
print(np.median(a, axis=1)) # [2. 5.]
11.4 mean()
沿指定的轴,计算数组中元素的算术平均值(即元素之总和除以元素数量)
a = np.array([[-1, 2, 3], [4, -5, 6]])
print(np.mean(a)) #1.5
print(np.mean(a, axis=0)) # [ 1.5 -1.5 4.5]
print(np.mean(a, axis=1)) # [1.33333333 1.66666667]
11.5 average()、var()、std()
-
1、 average() 加权平均值是将数组中各数值乘以相应的权数,然后再对权重值求总和,最后以权重的总和除以总的单位数(即因子个数);根据在数组中给出的权重,计算数组元素的加权平均值。该函数可以接受一个轴参数 axis,如果未指定,则数组被展开为一维数组。
加权平均值 = ∑ i = 1 n ( x i ⋅ w i ) ∑ i = 1 n w i 加权平均值=\dfrac{∑_{i=1}^n(x_i⋅w_i)}{∑_{i=1}^nw_i} 加权平均值=∑i=1nwi∑i=1n(xi⋅wi)
其中 xi是数组中的元素,wi是对应的权重。如果所有元素的权重之和等于1,则表示为数学中的期望值。
arr = np.array([1, 2, 4, 5, 6])
weight = np.array([0.1, 0.2, 0.1, 0.4, 0.5])
print(np.average(arr, weights=weight)) # 4.538461538461538
-
2 、在 NumPy 中,计算方差var()时使用的是统计学中的方差公式,而不是概率论中的方差公式,主要是因为 NumPy 的设计目标是处理实际数据集,而不是概率分布。
np.var 函数默认计算的是总体方差(Population Variance),而不是样本方差(Sample Variance)。
总体方差:
对于一个总体数据集 X={x1,x2,…,xN},总体方差的计算公式为:
σ 2 = 1 N ∑ i = 1 N ( x i − μ ) 2 σ^2=\dfrac{1}{N}∑_{i=1}^N(x_i−μ)^2 σ2=N1i=1∑N(xi−μ)2
其中:- N是总体数据点的总数。
- μ是总体的均值。
arr = np.array([1, 2, 4, 5, 6])
print(np.var(arr)) #3.44
- 3 、 std()标准差是方差的算术平方根,用来描述一组数据平均值的分散程度。若一组数据的标准差较大,说明大部分的数值和其平均值之间差异较大;若标准差较小,则代表这组数值比较接近平均值
arr = np.array([1, 2, 4, 5, 6])
print(np.std(arr)) # 1.8547236990991407

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)