1.基础
1.1 概念
NumPy 的全称是“ Numeric Python”,它是 Python 的第三方扩展包,主要用来计算、处理一维或多维数组
在数组算术计算方面, NumPy 提供了大量的数学函数
NumPy 的底层主要用 C语言编写,因此它能够高速地执行数值计算
NumPy 还提供了多种数据结构,这些数据结构能够非常契合的应用在数组和矩阵的运算上
1.2 优点
NumPy 可以很便捷高效地处理大量数据,使用 NumPy 做数据处理的优点如下:
NumPy 是 Python 科学计算基础库
NumPy 可以对数组进行高效的数学运算
NumPy 的 ndarray 对象可以用来构建多维数组
NumPy 能够执行傅立叶变换与重塑多维数组形状
NumPy 提供了线性代数,以及随机数生成的内置函数
1.3 与python列表区别
NumPy 数组是同质数据类型(homogeneous),即数组中的所有元素必须是相同的数据类型。数据类型在创建数组时指定,并且数组中的所有元素都必须是该类型。
Python 列表是异质数据类型(heterogeneous),即列表中的元素可以是不同的数据类型。列表可以包含整数、浮点数、字符串、对象等各种类型的数据。
NumPy 数组提供了丰富的数学函数和操作,如矩阵运算、线性代数、傅里叶变换等。
Python 列表提供了基本的列表操作,如添加、删除、切片、排序等。
1.4 安装
1 首先打开cmd面板
2 输入 conda create -n python-numpy python=3.9
3 点击安装
4 安装完成后输入pip install numpy==1.26.0
2.ndarray
NumPy 定义了一个 n 维数组对象,简称 ndarray 对象,它是一个一系列相同类型元素组成的数组集合。数组中的每个元素都占有大小相同的内存块,您可以使用索引或切片的方式获取数组中的每个元素。
ndarray 对象采用了数组的索引机制,将数组中的每个元素映射到内存块上,并且按照一定的布局对内存块进行排列,常用的布局方式有两种,即按行或者按列。
主要特点
多维数组:ndarray 可以表示任意维度的数组,包括一维、二维、三维等。
同质数据类型:ndarray 中的所有元素必须是相同的数据类型。
高效内存布局:ndarray 在内存中是连续存储的,这使得数组的访问和操作非常高效。
丰富的功能和方法:ndarray 提供了丰富的数学函数和操作,如矩阵运算、线性代数、傅里叶变换等。
使用方式:
ndarray 是通过 array 函数或其他 NumPy 函数(如 zeros、ones、arange 等)创建的。
array 函数接受一个序列作为输入,并返回一个 ndarray 对象。
2.1 array创建对象
通过 NumPy 的内置函数 array() 可以创建 ndarray 对象,其语法格式如下:
numpy.array(object, dtype = None, copy = True, order = None,ndmin = 0)
参数说明:
序号 | 参数 | 描述说明 |
---|---|---|
1 | object | 表示一个数组序列 |
2 | dtype | 可选参数,通过它可以更改数组的数据类型 |
3 | copy | 可选参数,表示数组能否被复制,默认是 True |
4 | order | 以哪种内存布局创建数组,有 3 个可选值,分别是 C(行序列)/F(列序列)/A(默认) |
5 | ndmin | 用于指定数组的维度 |
2.2 zeros()
创建指定大小的数组,数组元素以 0 来填充
格式:
numpy.zeros(shape, dtype = float, order = 'C')
参数 | 描述 |
---|---|
shape | 数组形状 |
dtype | 数据类型,可选 |
order | 'C' 用于 C 的行数组,或者 'F' 用于 FORTRAN 的列数组 |
2.3 ones()
创建指定形状的数组,数组元素以 1 来填充
格式:
numpy.ones(shape, dtype = None, order = 'C')
参数 | 描述 |
---|---|
shape | 数组形状 |
dtype | 数据类型,可选 |
order | 'C' 用于 C 的行数组,或者 'F' 用于 FORTRAN 的列数组 |
2.4 full()
full()用于创建一个填充指定值的数组。
格式:
numpy.full(shape, fill_value, dtype=None, order='C')
参数 | 描述 |
---|---|
shape | 数组的形状(如 (2, 3) 表示 2 行 3 列的数组) |
fill_value | 填充的值 |
dtype | 数组的数据类型(如 np.float32 ) |
order | 数组的内存布局(如 'C' 表示 C 风格,'F' 表示 Fortran 风格) |
2.5 arange()
arange() 函数用于创建一个等差数列的数组。它类似于 Python 内置的 range() 函数,但返回的是一个 NumPy 数组而不是一个列表。
格式:
numpy.arange(start, stop, step, dtype)
根据 start 与 stop 指定的范围以及 step 设定的步长,生成一个 ndarray。
参数 | 描述 |
---|---|
start | 起始值,默认为 0 |
stop | 终止值(不包含) |
step | 步长,默认为 1 |
dtype | 返回 ndarray 的数据类型,如果没有提供,则会使用输入数据的类型 |
案例1:
案例2:
案例3:
注意:
arange() 函数生成的数组不包含 stop 值。
如果 step 为负数,则 start 必须大于 stop,否则生成的数组为空。
arange() 函数在处理浮点数时可能会出现精度问题,因为浮点数的表示和计算存在精度误差。
2.6 linspace
在指定的数值区间内,返回均匀间隔的一维等差数组,默认均分 50 份
格式:
np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
参数 | 描述 |
---|---|
start | 起始值,默认为 0 |
stop | 终止值(默认包含) |
num | 表示数值区间内要生成多少个均匀的样本,默认值为 50 |
endpoint | 默认为 True,表示数列包含 stop 终止值,反之不包含 |
retstep | 表示是否返回步长。如果为 True,则返回一个包含数组和步长的元组;如果为 False,则只返回数组。默认为 False。 |
dtype | 返回 ndarray 的数据类型,默认为 None,表示根据输入参数自动推断数据类型。 |
案例:
说明:以上几个函数通常用于创建数字类型的数组,也可以用于创建布尔、字符串等类型的数组。但更适合用于创建数字数组。
3.数据类型
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_`代替 |
3.1 数据类型对象
数据类型对象(Data Type Object)又称 dtype 对象,是用来描述与数组对应的内存区域如何使用。
1.可以在创建数组时指定 dtype 参数来定义数组中元素的数据类型。
例如:
arr_str = np.array([1,2,3],dtype=np.string_) print(arr_str) #输出: AttributeError: `np.string_` was removed in the NumPy 2.0 release. Use `np.bytes_` instead. arr_str = np.array([1,2,3],dtype=np.unicode_) print(arr_str) # 输出: AttributeError: `np.unicode_` was removed in the NumPy 2.0 release. Use `np.str_` instead.
2.可以使用数组的 dtype 属性来获取数组中元素的数据类型。
例如:
3.可以使用 astype() 方法来转换数组中元素的数据类型。
例如:
3.2 数据类型标识码
NumPy 中每种数据类型都有一个唯一标识的字符码,int8, int16, int32, int64 四种数据类型可以使用字符串 'i1', 'i2','i4','i8' 代替,如下所示:
字符 | 对应类型 |
---|---|
b | 代表布尔型 |
i | 带符号整型 |
u | 无符号整型 |
f | 浮点型 |
c | 复数浮点型 |
m | 时间间隔(timedelta) |
M | datatime(日期时间) |
O | Python对象 |
S,a | 字节串(S)与字符串(a) |
U | Unicode |
V | 原始数据(void) |
以下是 NumPy 中常见的数据类型标识码及其对应的详细列表:
整数类型
数据类型 | 标识码 | 描述 |
---|---|---|
int8 | i1 | 8 位有符号整数 |
int16 | i2 | 16 位有符号整数 |
int32 | i4 | 32 位有符号整数 |
int64 | i8 | 64 位有符号整数 |
uint8 | u1 | 8 位无符号整数 |
uint16 | u2 | 16 位无符号整数 |
uint32 | u4 | 32 位无符号整数 |
uint64 | u8 | 64 位无符号整数 |
浮点数类型
数据类型 | 标识码 | 描述 |
---|---|---|
float16 | f2 | 16 位浮点数(半精度) |
float32 | f4 | 32 位浮点数(单精度) |
float64 | f8 | 64 位浮点数(双精度) |
复数类型
数据类型 | 标识码 | 描述 |
---|---|---|
complex64 | c8 | 64 位复数(单精度) |
complex128 | c16 | 128 位复数(双精度) |
布尔类型
数据类型 | 标识码 | 描述 |
---|---|---|
bool | b1 | 布尔类型 |
字符串类型
数据类型 | 标识码 | 描述 |
---|---|---|
bytes | S10 | 长度为 10 的字节串 |
str | U10 | 长度为 10 的 Unicode 字符串 |
Python 对象类型
数据类型 | 标识码 | 描述 |
---|---|---|
O | O | Python 对象类型 |
例如:自定义一个int32的数据类型
dt=np.dtype('i4') data = np.array([1,2,3,4],dtype=dt) print(data) #输出:[1 2 3 4] print(data.dtype) #输出:int32
可以自定义复杂的数据结构:
dt=np.dtype([('name','S10'),('age','i4')]) data = np.array([('zhangsan',20),('lisi',21)],dtype=dt) print(data) #输出:[(b'zhangsan', 20) (b'lisi', 21)] print(data.dtype) #输出:[('name', 'S10'), ('age', '<i4')]
说明:
在编程中,字节序标记用于指定数据的字节顺序。常见的字节序标记包括:
<
: 小端序,数据的最低有效字节存储在内存的最低地址,而最高有效字节存储在内存的最高地址。
>
: 大端序,数据的最高有效字节存储在内存的最低地址,而最低有效字节存储在内存的最高地址。
4.数组属性
4.1 shape
返回一个元组,元组中的每个元素表示数组在对应维度上的大小。元组的长度等于数组的维度数。
shape 属性功能:
-
返回一个由数组维度构成的元组
-
通过赋值,可以用来调整数组维度的大小
def shape_test(): array_one = np.array([[1,2,3],[4,5,6]]) print('array_one 原数组维度:',array_one.shape) print('array_one 原数组内容:',array_one) array_one.shape = (3,2) print('array_one 转变数组维度大小之后的数组维度:',array_one.shape) print('array_one 转变数组维度大小之后的数组内容:',array_one)
如果使用shape属性修改数组的形状,则修改的是原数组的形状,reshape修改数组的形状会返回一个新数组,不修改原数组的形状。
在 NumPy 中,
shape[0]
表示数组在第一个维度上的大小。换句话说,它返回数组的第一个维度的长度。arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # 输出: (2, 3)
print(arr.shape[0]) # 输出: 2
arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(arr.shape) # 输出: (2, 2, 2)
print(arr.shape[0]) # 输出: 2
4.2 数组维度
数组的维度就是一个数组中的某个元素,当用数组下标表示的时候,需要用几个数字来表示才能唯一确定这个元素,这个数组就是几维
ndmin
是 NumPy 中用于创建数组时指定最小维度的参数。它通常在 numpy.array()
函数中使用。通过 ndmin
,你可以确保生成的数组至少具有指定的维度。
ndim
是 NumPy 数组的一个属性,用于返回数组的维度数(即数组的秩)。它表示数组有多少个维度。
案例:
import numpy as np # 指定/查看数组维度 def ndmin_test(): threeArray = np.array([1,2,3,4],ndmin=2) print("ndmin 指定数组:",threeArray) print("ndmin 指定数组:",type(threeArray)) print("ndim 查看维度:",threeArray.ndim)
4.3 flags
flags 属性功能:
-
返回 ndarray 数组的内存信息
''' flags 属性功能: 1、返回 ndarray 数组的内存信息 ''' def flags_test(): array_one = np.array([[1,2,3],[4,5,6]]) print('array_one 数数组的内存信息:\n',array_one.flags)
输出:
C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : True WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False
说明:
C_CONTIGUOUS: 表示数组在内存中是 C 风格连续的(行优先)。 如果为 True,则数组是 C 风格连续的。 F_CONTIGUOUS: 表示数组在内存中是 Fortran 风格连续的(列优先)。 如果为 True,则数组是 Fortran 风格连续的。 OWNDATA: 表示数组是否拥有自己的数据(即是否是视图)。 如果为 True,则数组拥有自己的数据;如果为 False,则数组可能是从另一个数组或对象借用数据的。 WRITEABLE: 表示数组是否可写。 如果为 True,则数组是可写的;如果为 False,则数组是只读的。 ALIGNED: 表示数组是否对齐。 如果为 True,则数组的数据在内存中是对齐的。 WRITEBACKIFCOPY: 表示数组是否是通过 np.copy 创建的副本,并且需要将更改写回原始数组。 如果为 True,则数组是通过 np.copy 创建的副本,并且需要将更改写回原始数组。 UPDATEIFCOPY: 表示数组是否是通过 np.copy 创建的副本,并且需要将更改写回原始数组。 如果为 True,则数组是通过 np.copy 创建的副本,并且需要将更改写回原始数组。
5.切片
ndarray 对象的内容可以通过索引或切片来访问和修改,与 Python 中 list 的切片操作一样;
5.1 slice()
在 Python 中,slice 可以作为一个对象来使用。你可以创建一个 slice 对象,然后使用它来获取序列的片段。
参数:
start 是切片开始的位置(包含该位置)。
stop 是切片结束的位置(不包含该位置)。
step 是切片的步长,即选取元素的间隔。
案例:
slice 操作也可通过 [start:stop:step] 的形式来实现
冒号 : 的作用
表示范围: 冒号用于表示一个范围。例如,array[1:3] 表示从索引 1 到索引 3(不包括 3)的元素。
表示所有元素: 单独使用冒号表示所有元素。例如,array[:, 1] 表示所有行的第 1 列。
步长: 双冒号后面可以跟一个步长值,表示每隔多少个元素取一个。例如,array[::2] 表示每隔一个元素取一个。
注:冒号对于一维数组按索引号截取,二维数组按行和列截取。
省略号 ... 的作用
表示所有维度: 省略号用于表示数组的所有维度。例如,array[..., 1] 表示取所有行的第 1 列。
简化多维切片: 在多维数组中,省略号可以简化切片操作,避免显式地写出所有维度的索引。
注意:slice返回的数组是原数组的一个视图,修改数据会影响原数组中的数据。
我修改了数组2里面的数据后,数组1里面的数据也改变了
6.高级索引
NumPy 中的高级索引指的是使用整数数组、布尔数组或者其他序列来访问数组的元素。相比于基本索引,高级索引可以访问到数组中的任意元素,并且可以用来对数组进行复杂的操作和修改。
6.1 整数数组索引
整数数组索引是指使用一个数组来访问另一个数组的元素。这个数组中的每个元素都是目标数组中某个维度上的索引值。
适用于需要访问非连续元素或特定位置元素的场景。
注意:返回的新数组是一个副本,修改它不会影响原数组。
案例:
取出 4 * 3 数组四个角的数据:
行级别的列表索引:
由于 [[2], [1]] 是一个列向量(形状为 (2, 1)),而 [0, 1, 2] 是一个行向量(形状为 (3,)),NumPy 会通过广播机制将它们组合成一个 (2, 3) 的输出。
6.2 布尔索引
布尔索引通过布尔运算(如:比较运算符)来获取符合指定条件的元素的数组。
案例1:一维数组的布尔索引
通过bool_idx = arr >5 得到需要的数据 ,用满足条件的数据来生成行的数组
案例2:多维数组的布尔索引
案例3:切片布尔索引
arr[:, 2]
获取数组的第三列(索引从0开始):[2, 5, 8]
。
arr[:, 2] > 3
判断第三列的值是否大于3,结果是一个布尔数组:[False, True, True]
。
arr[arr[:, 2] > 3]
使用布尔数组对原数组进行行筛选,返回第三列值大于3的行:
arr[1]
获取数组的第二行:[3, 4, 5]
。
arr[1] > 3
判断第二行的值是否大于3,结果是一个布尔数组:[False, True, True]
。
arr[:, arr[1] > 3]
使用布尔数组对原数组的列进行筛选,返回满足条件的列:
案例4:
使用逻辑运算符(如 &、|、~)组合多个条件。
import numpy as np # 创建一个一维数组 arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) # 使用布尔索引筛选大于 5 且小于 9 的元素 bool_idx = (arr > 5) & (arr < 9) print(bool_idx) # 输出: [False False False False False True True True False False] # 使用布尔索引获取满足条件的元素 result = arr[bool_idx] print(result) # 输出: [6 7 8]
逻辑运算符:
&:与运算,组合多个条件。
|:或运算,组合多个条件。
~:非运算,取反条件。
7.广播(*)
广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。这要求维数相同,且各维度的长度相同,如果不相同,可以通过广播机制,这种机制的核心是对形状较小的数组,在横向或纵向上进行一定次数的重复,使其与形状较大的数组拥有相同的维度。
广播规则
-
维度匹配:如果两个数组的维度数不同,维度数较少的数组会在前面补上长度为 1 的维度。
-
形状匹配:如果两个数组在某个维度上的长度不同,但其中一个数组在该维度上的长度为 1,则该数组会沿着该维度进行广播。
-
不匹配:如果两个数组在某个维度上的长度既不相同也不为 1,则广播失败,抛出 ValueError。
案例1:一维数组与标量相加
标量 1 被广播到与 arr 相同的形状,然后进行逐元素相加。
案例2:二维数组与一维数组相加
arr1d 被广播到与 arr2d 相同的形状,然后进行逐元素相加。
arr1d是一维数组,arr2d是一个4行1列的二维数组,按行arr1d广播为4行,按列arr2d被广播为4列,最终成为4行4列的数组
案例3:二维数组与二维数组相加
arr2d_broadcast 被广播到与 arr2d 相同的形状,然后进行逐元素相加。
案例4:广播失败
8.遍历数组
8.1 遍历数组的第一维度
for i in arr:
遍历数组的第一维度,即按行或列的顺序逐个访问元素。
返回的是数组的子数组(如行或列),而不是单个元素。
8.2 nditer逐个访问元素
nditer 是 NumPy 中的一个强大的迭代器对象,用于高效地遍历多维数组。nditer 提供了多种选项和控制参数,使得数组的迭代更加灵活和高效。
控制参数
nditer 提供了多种控制参数,用于控制迭代的行为。
1.order 参数
order 参数用于指定数组的遍历顺序。默认情况下,nditer 按照 C 风格(行优先)遍历数组。
C 风格(行优先): order='C'
Fortran 风格(列优先): order='F'
# 使用 Fortran 风格遍历数组
2.flags 参数
flags 参数用于指定迭代器的额外行为。
multi_index: 返回每个元素的多维索引。
external_loop: 返回一维数组而不是单个元素,减少函数调用的次数,从而提高性能。
# 创建一个二维数组 # 注意:external_loop 和 order='F' 一起使用时,会将每列的元素打包成一个数组返回。
# 注意:external_loop 会将所有元素打包成一个数组返回,而不是按行打包。
9.数组操作
9.1 数组变维
函数名称 | 函数介绍 |
---|---|
reshape | 在不改变数组元素的条件下,修改数组的形状 |
flat属性 | 返回是一个迭代器,可以用 for 循环遍历其中的每一个元素 |
flatten | 以一维数组的形式返回一份数组的副本,对副本的操作不会影响到原数组 |
ravel | 返回一个连续的扁平数组(即展开的一维数组),与 flatten不同,它返回的是数组视图(修改视图会影响原数组) |
9.1.1 reshape
reshape() 函数允许你在不改变数组数据的情况下,改变数组的维度。
reshape() 返回的是一个新的数组,原数组的形状不会被修改。reshape() 可以用于多维数组,例如将一个一维数组重塑为二维数组。
但是,reshape后产生的新数组是原数组的一个视图,即它与原数组共享相同的数据,但可以有不同的形状或维度,且对视图的修改会直接影响原数组。
元素总数必须匹配:新形状中的元素总数必须与原数组中的元素总数相同。
例如,一个长度为6的一维数组可以被重塑为 (2, 3) 或 (3, 2),表示原数组被重塑为2行3列或3行2列的数组,但不能被重塑为 (2, 2)。
案例:
将数组改变为二维数组:
-1 作为占位符:你可以使用 -1 作为占位符,让 numpy 自动计算某个维度的大小。
例如:
reshape() 还可以将一维数组重塑为三维数组:
例如:
2 个层:最外层有 2 个块。
3 行:每个块中有 3 行。
2 列:每行有 2 列。
重要点:
元素总数不变:原数组有 12 个元素,重塑后的数组也必须有 12 个元素。
2 * 3 * 2 = 12
,所以这是合法的重塑操作。内存布局:
reshape
不会改变数组在内存中的存储顺序,只是改变了访问元素的方式。返回新数组:
reshape
方法返回一个新的数组,而不会修改原数组。
9.1.2 flat
返回一个一维迭代器,用于遍历数组中的所有元素。无论数组的维度如何,ndarray.flat属性都会将数组视为一个扁平化的一维数组,按行优先的顺序遍历所有元素。
语法:
ndarray.flat
案例:
9.1.3 flatten()
用于将多维数组转换为一维数组。flatten() 返回的是原数组的一个拷贝,因此对返回的数组进行修改不会影响原数组。
语法:
ndarray.flatten(order='C')
参数
order: 指定数组的展开顺序。
'C'
:按行优先顺序展开(默认)。
'F'
:按列优先顺序展开。
'A'
:如果原数组是 Fortran 连续的,则按列优先顺序展开;否则按行优先顺序展开。
'K'
:按元素在内存中的顺序展开。
案例:
如果order='F',输出结果是什么?
会按照列来输出。
9.1.4 ravel()
用于将多维数组转换为一维数组。与 flatten() 不同,ravel() 返回的是原数组的一个视图(view),而不是副本。因此,对返回的数组进行修改会影响原数组。
语法:
ndarray.ravel()
参数
order: 指定数组的展开顺序。
'C'
:按行优先顺序展开(默认)。
'F'
:按列优先顺序展开。
'A'
:如果原数组是 Fortran 连续的,则按列优先顺序展开;否则按行优先顺序展开。
'K'
:按元素在内存中的顺序展开。
案例:
9.2 数组转置
函数名称 | 说明 |
---|---|
transpose | 将数组的维度值进行对换,比如二维数组维度(2,4)使用该方法后为(4,2) |
ndarray.T | 与 transpose 方法相同 |
案例:
9.3 升维和降维
多维数组(也称为 ndarray)的维度(或轴)是从外向内编号的。这意味着最外层的维度是轴0,然后是轴1,依此类推。
函数名称 | 参数 | 说明 |
---|---|---|
expand_dims(arr, axis) | arr:输入数组 axis:新轴插入的位置 | 在指定位置插入新的轴(相对于结果数组而言),从而扩展数组的维度 |
squeeze(arr, axis) | arr:输入数的组 axis:取值为整数或整数元组,用于指定需要删除的维度所在轴,指定的维度值必须为 1 ,否则将会报错,若为 None,则删除数组维度中所有为 1 的项 | 删除数组中维度为 1 的项 |
案例1:增加数组维度
创建了一个一维数组
a
,其形状为(3,)
,表示数组有 3 个元素。
np.expand_dims(a, axis=0)
在数组a
的第 0 维(最外层)插入一个新维度。插入后,数组
b
的形状变为(1, 3)
,表示有一个行向量,包含 3 个元素。
np.expand_dims(a, axis=1)
在数组a
的第 1 维插入一个新维度。插入后,数组
c
的形状变为(3, 1)
,表示有 3 个列向量,每个列向量包含 1 个元素。
案例2:适应广播操作
案例3:移除长度为1的维度
数组结构:
c
是一个三维数组,其结构可以想象成一个三维的盒子。最外层是一个包含1个元素的列表(第一个维度)。
中间层也是一个包含1个元素的列表(第二个维度)。
最内层是一个包含3个元素的列表(第三个维度)。
第一层(最外层)看,有两个元素;第二层有一个元素;第三层,有三个元素;
删除了第一维,最外层看就有两个元素,然后第二层看,有三个元素。
9.4 连接数组
函数名称 | 参数 | 说明 |
---|---|---|
hstack(tup) | tup:可以是元组,列表,或者numpy数组,返回结果为numpy的数组 | 按水平顺序堆叠序列中数组(列方向) |
vstack(tup) | tup:可以是元组,列表,或者numpy数组,返回结果为numpy的数组 | 按垂直方向堆叠序列中数组(行方向) |
hstack函数要求堆叠的数组在垂直方向(行)上具有相同的形状。如果行数不一致,hstack() 将无法执行,并会抛出 ValueError 异常。
vstack() 要求堆叠的数组在水平方向(列)上具有相同的形状。如果列数不一致,将无法执行堆叠操作。
vstack() 和 hstack() 要求堆叠的数组在某些维度上具有相同的形状。如果维度不一致,将无法执行堆叠操作。
案例:
hstack:
只有维度数一致的时候才能堆叠,否则报错,错误的原因是,一个是二行,另外一个是三行,就会报错。
vstack:
9.5 分割数组
函数名称 | 参数 | 说明 |
---|---|---|
hsplit(ary, indices_or_sections) | ary:原数组 indices_or_sections:按列分割的索引位置 | 将一个数组水平分割为多个子数组(按列) |
vsplit(ary, indices_or_sections) | ary:原数组 indices_or_sections:按行分割的索引位置 | 将一个数组垂直分割为多个子数组(按行) |
案例:
9.6 矩阵运算
np.dot
是一个通用的点积函数,适用于多种维度的数组。
对于二维数组(矩阵),np.dot
等价于矩阵乘法。
对于一维数组(向量),np.dot
计算的是向量的点积(内积)。
案例1:矩阵运算
矩阵乘法:
矩阵乘法的规则是:第一个矩阵的行与第二个矩阵的列进行逐元素相乘并求和。
计算结果矩阵的每个元素:
第一行第一列:
1*5 + 2*7 = 5 + 14 = 19
第一行第二列:
1*6 + 2*8 = 6 + 16 = 22
第二行第一列:
3*5 + 4*7 = 15 + 28 = 43
第二行第二列:
3*6 + 4*8 = 18 + 32 = 50
大一学的已经还给老师了哈哈哈
案例2:向量点积
计算公式为:
dot product=a1⋅b1+a2⋅b2+⋯+an⋅bn
np.matmul
是专门用于矩阵乘法的函数,适用于二维及更高维度的数组。
案例:矩阵相乘
np.dot是通用点积函数,np.matmul专门用于矩阵运算,性能要好于np.dot
np.linalg.det
计算一个方阵(行数和列数相等的矩阵)的行列式。
案例:
结果不是-2,这是由于浮点数的二进制表示和计算过程中的舍入误差导致的。可以通过四舍五入来近似表示:
det_a = np.round(np.linalg.det(a))
10.数组元素的增删改查
10.1 resize
函数名称 | 参数 | 说明 |
---|---|---|
resize(a, new_shape) | a:操作的数组 new_shape:返回的数组的形状,如果元素数量不够,重复数组元素来填充新的形状 | 返回指定形状的新数组 |
案例:
最后一行代码将数组形状修改为(3, 4),原数组的元素数量不够,则重复原数组的元素填充。
10.2 append
函数名称 | 参数 | 说明 |
---|---|---|
append(arr, values, axis=None) | arr:输入的数组 values:向 arr 数组中添加的值,需要和 arr 数组的形状保持一致 axis:默认为 None,返回的是一维数组;当 axis =0 时,追加的值会被添加到行,而列数保持不变,若 axis=1 则与其恰好相反 | 在数组的末尾添加值,返回一个一维数组 |
案例:
'''
append(arr, values, axis=None) 函数:
1、将元素值添加到数组的末尾,返回一个一维数组
2、arr:输入的数组
3、values:向 arr 数组中添加的值,需要和 arr 数组的形状保持一致
4、axis:默认为 None,返回的是一维数组;当 axis =0 时,追加的值会被添加到行,而列数保持不变,若 axis=1 则与其恰好相反
'''
10.3 insert
函数名称 | 参数 | 说明 |
---|---|---|
insert(arr, obj, values, axis) | arr:输入的数组 obj:表示索引值,在该索引值之前插入 values 值 values:要插入的值 axis:默认为 None,返回的是一维数组;当 axis =0 时,追加的值会被添加到行,而列数保持不变,若 axis=1 则与其恰好相反 | 沿规定的轴将元素值插入到指定的元素前 |
案例:
如果obj为-1,表示插入在倒数第一个元素之前,不是在最后一列。
10.4 delete
函数名称 | 参数 | 说明 |
---|---|---|
delete(arr, obj, axis) | arr:输入的数组 obj:表示索引值,要删除数据的索引 axis:默认为 None,返回的是一维数组;当 axis =0 时,删除指定的行,若 axis=1 则与其恰好相反 | 删掉某个轴上的子数组,并返回删除后的新数组 |
案例:
一维数组:
二维数组:
np.arange(6)
生成一个包含 0 到 5 的一维数组:[0, 1, 2, 3, 4, 5]
。
.reshape(2, 3)
将数组重新塑形为一个 2 行 3 列的二维数组:
axis=None
表示将数组展平为一维,然后删除索引为 1 的元素。展平后的数组是
[0, 1, 2, 3, 4, 5]
,删除索引 1 的元素后结果为[0, 2, 3, 4, 5]
。
axis=0
表示删除行。索引为 1 的行是[3, 4, 5]
,删除后结果为:
[[0 1 2]]
axis=1
表示删除列。索引为 1 的列是[1, 4]
,删除后结果为:
10.5 argwhere
返回数组中非 0 元素的索引,若是多维数组则返回行、列索引组成的索引坐标
案例:
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:返回唯一元素的索引
逆索引是什么:在数组里面第一次出现的数,标记为0,第一次出现的第二个数标记为1,依次类推,然后后续遇到之前这个数,签名标记为多少,它就是多少。
案例2:返回唯一元素及其逆索引
案例3:返回唯一元素的计数
对于多维数组,unique 函数同样适用。默认情况下,unique 函数会将多维数组展平为一维数组,然后查找唯一元素。
11.统计函数
11.1 amin() 和 amax()
计算数组沿指定轴的最小值与最大值,并以数组形式返回
对于二维数组来说,axis=1 表示沿着水平方向,axis=0 表示沿着垂直方向
案例:
''' numpy.amin() 和 numpy.amax() 函数: 1、计算数组沿指定轴的最小值与最大值,并以数组形式返回 2、对于二维数组来说,axis=1 表示沿着水平方向,axis=0 表示沿着垂直方向 '''![]()
按1轴求最小值,表示在最内层轴中(每列中)分别找最小值;按1轴求最小值表示在最外层轴中(所有行中按列)找最小值。求最大值类似。
11.2 ptp()
计算数组元素中最值之差值,即最大值 - 最小值
对于二维数组来说,axis=1 表示沿着水平方向,axis=0 表示沿着垂直方向
11.3 median()
用于计算中位数,中位数是指将数组中的数据按从小到大的顺序排列后,位于中间位置的值。如果数组的长度是偶数,则中位数是中间两个数的平均值。
11.4 mean()
沿指定的轴,计算数组中元素的算术平均值(即元素之总和除以元素数量)
11.5 average()
加权平均值是将数组中各数值乘以相应的权数,然后再对权重值求总和,最后以权重的总和除以总的单位数(即因子个数);根据在数组中给出的权重,计算数组元素的加权平均值。该函数可以接受一个轴参数 axis,如果未指定,则数组被展开为一维数组。
其中 xi是数组中的元素,wi是对应的权重。
如果所有元素的权重之和等于1,则表示为数学中的期望值。
11.6 var()
在 NumPy 中,计算方差时使用的是统计学中的方差公式,而不是概率论中的方差公式,主要是因为 NumPy 的设计目标是处理实际数据集,而不是概率分布。
np.var 函数默认计算的是总体方差(Population Variance),而不是样本方差(Sample Variance)。
总体方差与样本方差的区别
总体方差(Population Variance):
公式:
适用于整个数据集(总体)。
NumPy 的
np.var
默认使用这个公式。样本方差(Sample Variance):
公式:
适用于从总体中抽取的样本。
需要手动调整自由度(
ddof
参数)来计算。
11.7 std()
标准差是方差的算术平方根,用来描述一组数据平均值的分散程度。若一组数据的标准差较大,说明大部分的数值和其平均值之间差异较大;若标准差较小,则代表这组数值比较接近平均值
1. 总体标准差
总体标准差的公式为:
N 是数据集的总样本数。
xi 是数据集中的每个值。
μ 是总体均值。
2. 样本标准差
样本标准差的公式为:
N 是样本的大小。
xi 是样本中的每个值。
xˉ 是样本均值。
N−1 是自由度(用于无偏估计)。
在 NumPy 中计算标准差
NumPy 提供了
np.std
函数来计算标准差,默认计算的是总体标准差。如果需要计算样本标准差,可以通过设置ddof=1
参数来调整自由度。