Jiang_hh

导航

 

numpy学习

前言

本节内容目录清晰,可以依据目录进行查找相应的方法完成对应操作
导入:

import numpy as np

1. 出现原因

为什么需要Numpy?

它是python专门设计的一个工具库,适合高性能的数据处理应用场景。

如下例子:可以清楚对比出numpy数组和list数组计算同一个操作展现出的性能差异

import time

# 创建一个0-999999 python列表
py_list = list(range(1000000))
# 创建一个0-999999的numpy数组
np_arr = np.arange(1000000)

start = time.time() # 记录当前时间


# Python 方式:用列表推导式对每个元素求平方,再用 sum() 求和
sum([x ** 2 for x in py_list])
print(f"Python列表耗时:{time.time() - start:.4f}s") # 耗时0.2591s

start = time.time()

# NumPy 方式:直接对整个数组做平方(向量化运算),再用 np.sum() 求和
np.sum(np_arr ** 2)
# 采用f"..."格式化字符串,{}里的内容会计算后进行嵌入到字符串里
# :是分隔符,左边是格式化的值,右边是格式化的格式,也就是保留4位小数
print(f"NumPy数组耗时:{time.time() - start:.4f}s")  # 耗时0.0109s

2.ndarray介绍 -- numpy核心

2.1 ndarray的核心特性

  1. 多维性:支持0维度,1维度(向量,一维数组),2维度(矩阵),以及更高维度的数组
  2. 同质性:所有元素类型必须一致(即使你定义时不一致,最后也会类型上升统一到一致,这样是为了快速计算),可以通过dtype制定
  3. 高效性:基于连续的内存块进行存储,支持向量化计算

2.1.1 多维性

支持0维度,1维度(向量,一维数组),2维度(矩阵),以及更高维度的数组

import numpy as np

# 创建一个0维度的ndarry
arr1 = np.array(1)
print(arr1.ndim)
# 创建一个1维度的ndarrry
arr2 = np.array([1,2,3,4])
print(arr2.ndim)
# 创建一个2维度的ndarray
arr3 = np.array([[1,2,3],[2,3,4]])
print(arr3.ndim)

2.1.2 同质性

所有元素类型必须一致(即使你定义时不一致,最后也会类型上升统一到一致,这样是为了快速计算),可以通过dtype制定

# 制定类型进行创建
arr1 = np.array([1,2,3],dtype=np.int64)
print(arr1.dtype)
arr1 = np.array([1,2,3],dtype=np.int32)
print(arr1.dtype)
arr1 = np.array([1,2,3],dtype=np.float64)
print(arr1.dtype)
# 即使数据类型不一致,也会进行类型的转换
arr2 = np.array([1,2,'nihao'])
print(arr2.dtype) # 整体转为U11类型,就是11个固定长度的字符,必须要保证每一个元素的字节一样,才能高速计算
print(arr2)
arr3 = np.array([1,2,3.2])
print(arr3.dtype) # 整体转为float64类型
print(arr3)

2.1.3 高效性

基于连续的内存块进行存储,可以随机读写数据,支持向量化计算与广播特性

2.2 ndarray属性

shape: 数组的形状:行数和列数(或更高维度的尺寸)。

ndim: 维度数量:数组是几维的(1维、2维、3维等)。

size: 总元素个数:数组中所有元素的总数。

dtype: 元素类型:数组中元素的类型(整数、浮点数等)。

T: 转置:行变列,列变行。

===== 不太常用:=====

itemsize: 单个元素占用的内存字节数。

nbytes: 数组总内存占用量:size * itemsize。

flags: 内存存储方式:是否连续存储(高级优化)。

arr1 = np.array([[1,2,3],[2,3,4]])
print("形状:",arr1.shape)
print("维度:",arr1.ndim)
print("size = ",arr1.size)
print("类型",arr1.dtype)
print("转置",arr1.T)
print("原数组",arr1)

3 ndarray的创建

主要有如下几类:具体的应用场景如下:

1.基础构造: 适用于手动构建小规模数组或复制已有数据。

2.预定义形状填充: 用于快速初始化固定形状的数组(如全0占位、全1初始化)。

3.基于数值范围生成: 生成数值序列,常用于模拟时间序列、坐标网格等。

4.特殊矩阵生成: 数学运算专用(如线性代数中的单位矩阵)。

5.随机数组生成: 模拟实验数据、初始化神经网络权重等场景。

6.高级构造方法: 处理非结构化数据(如文件、字符串)或通过函数生成复杂数组。

3.1 基础构造

3.1.1 np.array()

np.array():将列表/元组转换为 ndarray

例:np.array([[1, 2], [3, 4]])

import numpy as np
arr1 = np.array([1,2,3,4])
print(arr1)
[1 2 3 4]
list = [1,2,3,4,5]
arr2 = np.array(list)
print(list)

3.1.2 np.copy()

np.copy(): 创建独立副本(深拷贝),与原数组相同但不共享内存,就是又new了一个

np.copy(arr)

import numpy as np
arr1 = np.array([1,2,3,4])
arr2 = np.copy(arr1)
print(arr1)
print(arr2)
arr2[2] = 5 # 进行修改又新生成的ndarray
print(arr1)
print(arr2)

3.2 预定义形状填充

3.2.1 np.zeros()

作用:根据传入的形状生成全0数组,快速初始化全0数组

调用:np.zeros(传入形状) 例:np.zeros((2,3))

zeros_arr = np.zeros((2,3))
print(zeros_arr)
zeros_arr = np.zeros((2,3),dtype=np.int64) # 指定类型
print(zeros_arr)
[[0. 0. 0.]
 [0. 0. 0.]]
[[0 0 0]
 [0 0 0]]

3.2.2 np.ones()

作用:根据传入的形状生成全1数组,快速初始化全1数组

调用:np.ones(传入形状) 例:np.ones((2,3))

ones_arr = np.ones((2,3))
print(ones_arr)
ones_arr = np.ones((2,3),dtype=np.int64)
print(ones_arr)
[[1. 1. 1.]
 [1. 1. 1.]]
[[1 1 1]
 [1 1 1]]

3.2.3 np.empty()

作用:生成一个未初始化的数组,主要进行预分配内存,里面的值不是随机值,而是未初始化的内存 — 直接拿分配到的内存块里原来的内容来用,不做任何初始化。

调用:np.empty(传入形状) 例:np.empty((2,3))

empty_arr = np.empty((2,3,5))
print(empty_arr)
[[[1.25398642e-311 1.02765654e-321 0.00000000e+000 0.00000000e+000
   1.16095442e-028]
  [5.02034658e+175 1.65713486e-076 9.94952968e-043 1.93334423e+184
   1.60496009e-051]
  [1.50032769e-076 5.83278374e-144 3.59751658e+252 3.96046095e+246
   1.04918621e-153]]

 [[7.69165785e+218 5.04621343e+180 1.04917822e-153 9.08366793e+223
   1.65713486e-076]
  [9.94952968e-043 1.93334423e+184 1.60496009e-051 1.04917697e-153
   1.94918966e-153]
  [1.10684845e-047 2.26301105e-076 2.10937826e-052 2.59027896e-144
   7.79952704e-143]]]

3.2.4 np.full()

作用:生成一个指定形状,指定值的ndarray数组,里面的值是指定的。

调用:np.full(传入形状,填充值) 例:np.full((2,3),2)

full_arr = np.full((2,3),1)
print(full_arr)
[[1 1 1]
 [1 1 1]]

3.3 基于数值范围生成

3.3.1 np.arange()

作用:生成一个等差序列,生成步长固定的序列(左闭右开),多使用生成[1,2,3,4,5]类似的数列

使用:np.arange(左起点,右终点,步长) 例:np.arange(0, 10, 2)

arange_arr = np.arange(0,11,1)
print(arange_arr)
[ 0  1  2  3  4  5  6  7  8  9 10]

3.3.2 np.linspace()

作用:生成一个等间隔序列,生成制定数量的等间隔值(左闭右闭)

使用:np.linspace(左起点,右终点,数量) 例:np.linspace(0, 10, 3) -> [ 0. 5. 10.] 间隔值:(10-0) / (3-1) = 5

linespace_arr = np.linspace(0,10,5)
print(linespace_arr)
[ 0.   2.5  5.   7.5 10. ]

3.3.3 np.logspace()

作用:生成一个生成对数间隔值,生成制定数量的等间隔值(左闭右闭)

使用:np.linspace(左起点,右终点,数量,底数) 例:np.logspace(0, 2, 3, base=10) -> [ 1. 10. 100.] 间隔值:(2-0) / (3-1) = 1 -> 0,1,2 -> 100,101,10^2

print(np.logspace(0, 2, 3, base=10))
[  1.  10. 100.]

3.4 特殊矩阵生成

3.4.1 np.eye()

作用:生成一个单位矩阵

使用:np.eye(维度) 例:np.eye(2)

注意:np.eye(行,列) 也可以,这样虽然不是单位矩阵,但是包含一个最大的单位矩阵

print(np.eye(2))
[[1. 0.]
 [0. 1.]]
print(np.eye(2,3))
[[1. 0. 0.]
 [0. 1. 0.]]
print(np.eye(3,2))
[[1. 0.]
 [0. 1.]
 [0. 0.]]

3.4.2 np.diag()

作用:生成一个对角矩阵

使用:np.diag(传入一个列表,长度是维度,值是对角线的值) 例:np.diag(1,2,2)

print(np.diag([1,2,3,4,5,6,7]))
[[1 0 0 0 0 0 0]
 [0 2 0 0 0 0 0]
 [0 0 3 0 0 0 0]
 [0 0 0 4 0 0 0]
 [0 0 0 0 5 0 0]
 [0 0 0 0 0 6 0]
 [0 0 0 0 0 0 7]]

3.5 随机数组

3.5.1 均匀分布随机数 (np.random.rand)

作用:返回给定形状的数组,用 [0, 1) 上均匀分布的随机样本填充。

用法: np.random.rand(传入形状) 例:np.random.rand(2, 2)

import numpy as np
random_arr = np.random.rand(5,2)

print(random_arr)
[[0.59865848 0.15601864]
 [0.15599452 0.05808361]
 [0.86617615 0.60111501]
 [0.70807258 0.02058449]
 [0.96990985 0.83244264]]

3.5.2 正态分布随机数 (np.random.randn)

作用:返回给定形状的数组,用标准正态分布(均值为0,标准差为1)的随机样本填充。 大部分位于-3-3之间

用法: np.random.randn(传入形状) 例:np.random.randn(2, 2)

randn_arr = np.random.randn(2,3)
print(randn_arr)
[[-0.58087813 -0.52516981 -0.57138017]
 [-0.92408284 -2.61254901  0.95036968]]

3.5.3 随机整数 (np.random.randint)

作用:返回给定形状的数组,用从低位(包含)到高位(不包含)上均匀分布的随机整数填充。左闭右开

用法: np.random.randint(左起点,右终点,(形状)) 例:int_arr = np.random.randint(1, 10, (2, 2)) # [1,10) 的整数

randint_arr = np.random.randint(2,10,(3,4))
print(randint_arr)
[[2 4 4 8]
 [3 9 5 5]
 [9 8 7 7]]

3.5.4 随机浮点数 (random.uniform())

作用:返回给定形状的数组,用从低位(包含)到高位(不包含)上均匀分布的随机浮点数填充。左闭右开

用法: np.random.uniform(左起点,右终点,(形状)) 例:int_arr = np.random.uniform(3, 6, (2, 3))

uni_arr = np.random.uniform(0,10,(2,3))
print(uni_arr)
[[7.85175961 1.99673782 5.14234438]
 [5.92414569 0.46450413 6.07544852]]

3.6 设置随机种子 (np.random.seed)

作用:np.random.seed 是 NumPy 中用于设置随机数生成器种子的函数,目的是确保程序的随机操作可以重复生成相同的结果(即保证随机结果的确定性)。这在实验复现、调试和教学场景中非常有用。

好处:
1.种子的一致性:相同种子生成的随机数序列完全一致。不同种子(如 np.random.seed(0) 和 np.random.seed(1))会产生不同序列。

2.作用范围:种子对后续所有基于 NumPy 的随机函数生效(如 np.random.rand(), np.random.normal() 等)。

通过控制种子,你能在"随机"和"可复现"之间灵活切换!

np.random.seed(42)

print(np.random.rand(3)) # 每一次结果都一样
[0.37454012 0.95071431 0.73199394]

3.7 高级构造方法

还未接触,后续补充,略

4 ndarray的数据类型

数据类型 类型代码 说明
bool 布尔类型
int8、uint8 i1, u1 有符号、无符号的 8 位(1 字节)整型
int16、uint16 i2, u2 有符号、无符号的 16 位(2 字节)整型
int32、uint32 i4, u4 有符号、无符号的 32 位(4 字节)整型
int64、uint64 i8, u8 有符号、无符号的 64 位(8 字节)整型
float16 f2 半精度浮点型
float32 f4 或 f 单精度浮点型
float64 f8 或 d 双精度浮点型
complex64 c8 用两个 32 位浮点数表示的复数
complex128 c16 用两个 64 位浮点数表示的复数

这里没有字符串类型,字符串类型一般使用<u数字表示

5 ndarry索引与切片技巧

5.1 基本索引 arr[索引]

作用:通过整数索引直接访问元素

用法:arr[索引]

例:arr[1,2]

import numpy as np
arr = np.random.randint(0,11,(10))
print(arr)
print(arr[1])
arr = np.random.randint(0,11,(2,3))
print(arr)
print(arr[0,1])
print(arr[1,2])
[3 6 7 2 0 3 1 7 3 1]
6
[[5 5 9]
 [3 5 1]]
5
1

5.2 切片 arr[start:stop:step]

作用:通过arr[start:stop:step]直接得到新的ndarry,左闭右开,::表示全默认开头结尾,步长为1

用法:一维:arr[start:stop:step] 二维: arr[start:stop:step,start:stop:step]

例:arr[:,2]

arr = np.random.randint(0,11,10)
print(arr)
print(arr[0:7]) # 切出0-7索引
[ 7  2  2  0 10  4  9  6  9  8]
[ 7  2  2  0 10  4  9]
arr = np.random.randint(0,11,10)
print(arr)
print(arr[0:7:2]) # 切出0-7索引,步长为2
[6 8 7 1 0 6 6 7 4 2]
[6 7 0 6]
arr = np.random.randint(0,11,(4,5))
print(arr)
print(arr[1,::]) # 要第二行
print(arr[1]) # 也可以达到相同的效果,但是这样就返回了一个一维数组,可以再次进行操作
print(arr[1,1:4])
print(arr[1][1:4]) # arr[1,1:4]效果一样,但是原理不同,后者类似链式调用
[[4 0 7 4 4]
 [6 3 5 3 2]
 [6 7 3 1 9]
 [2 0 7 2 9]]
[6 3 5 3 2]
[6 3 5 3 2]
[3 5 3]
[3 5 3]
arr = np.random.randint(0,11,(4,5))
print(arr)
print(arr[::,1]) # 要第二列
[[ 3  7  7  6  2]
 [ 0  0 10  2  5]
 [ 6  5  5  5  2]
 [ 5  7 10 10  1]]
[7 0 5 7]
arr = np.random.randint(0,11,(4,5))
print(arr)
print(arr[::,2]) # 行全要,列只要第二个索引
[[ 3  3  4  6  6]
 [10  3  6 10  2]
 [ 5  1  9  8  4]
 [ 5  3 10  9  6]]
[ 4  6  9 10]
arr = np.random.randint(0,11,(4,5))
print(arr)
print(arr[::2,2]) # 行每个一行要一个,列只要第二个索引
[[10  5  7  8  3]
 [ 0  0  9  3  6]
 [ 1  2  0  4  0]
 [ 7  0 10  0  1]]
[7 0]
arr = np.random.randint(0,11,(4,5))
print(arr)
print(arr[1:3:,1:4:]) # 取出里面那个小的2*3小矩阵
[[ 3  8  0  7  6]
 [ 1  7  0 10  8]
 [ 8  1  6  9  2]
 [ 6  9  8  3  0]]
[[ 7  0 10]
 [ 1  6  9]]

5.3 使用slice函数进行切片

通过 slice(start, stop, step) 定义切片规则。

arr = np.random.randint(0,11,10)
print(arr)
print(arr[slice(0,8,1)]) # 切出0-7索引
[6 9 4 9 4 6 8 4 0 9]
[6 9 4 9 4 6 8 4]
arr = np.random.randint(0,11,(5,5))
print(arr)
print(arr[slice(1,4,1),slice(1,4,1)]) # 切出内部3*3索引
[[ 6  3  0  4  6]
 [ 9  9  5  4  3]
 [ 1  3  9  9  2]
 [ 9  0  7  4  3]
 [ 7  6  1  0 10]]
[[9 5 4]
 [3 9 9]
 [0 7 4]]

5.4 使用布尔条件 arr[逻辑运算符]

作用:筛选满足条件的元素,支持逻辑运算符&,|

用法:arr[逻辑运算符]

注意:直接用布尔条件 arr[condition] 永远返回一维数组

arr = np.random.randint(0,11,10)
print(arr)
print(arr[arr > 5]) # 切出大于5的元素
[ 3  7  1  2  0  0  2 10  4  2]
[ 7 10]
arr = np.random.randint(0,11,(5,5))
print(arr)
print(arr[(arr > 3) & (arr < 5)]) # 切出3 - 5的元素
[[ 2  1  9  3  7]
 [ 8  6  0  2  8]
 [ 0  8  7  0  5]
 [ 4  5  9  4  5]
 [ 4 10  4  3  2]]
[4 4 4 4]

5.5 注意:内存共享特性

内存共享特性切片返回的是原数组的视图(共享内存),修改切片会影响原数组。需用 copy() 创建独立副本

arr = np.random.randint(0,11,(3,3))
print(arr)
arr[::] = 1 # 切片全置为1
print(arr)
[[10  5  0]
 [ 8  0  4]
 [ 3  2  5]]
[[1 1 1]
 [1 1 1]
 [1 1 1]]

6 基本运算

numpy中的数组不用编写循环即可执行批量运算,称之为矢量化运算。大小相等的数组之间的任何算术运算都会将运算应用到元素级。

6.1 四则运算

这里都是元素级别运算,就是位置相同的进行计算

a = np.random.randint(1,11,(3,3))
b = np.random.randint(1,11,(3,3))
print(a)
print(b)
print(a + b)
print(a - b)
print(a * b)
print(a / b)
[[ 8  2  8]
 [ 7 10 10]
 [ 2  6  6]]
[[3 2 1]
 [6 5 9]
 [1 7 5]]
[[11  4  9]
 [13 15 19]
 [ 3 13 11]]
[[ 5  0  7]
 [ 1  5  1]
 [ 1 -1  1]]
[[24  4  8]
 [42 50 90]
 [ 2 42 30]]
[[2.66666667 1.         8.        ]
 [1.16666667 2.         1.11111111]
 [2.         0.85714286 1.2       ]]

6.2 矩阵乘法 np.dot()、ndarray.dot()、@

要求:Amn @ Bnl 即前一个列和后一个行相同

a = np.random.randint(1,11,(3,3))
b = np.random.randint(1,11,(3,3))
print(a)
print(b)
print(a @ b)
print(np.dot(a,b))
print(a.dot(b))
[[ 2 10  6]
 [ 5  6  1]
 [ 5  9 10]]
[[ 2  1 10]
 [ 9 10  9]
 [ 9  6  8]]
[[148 138 158]
 [ 73  71 112]
 [181 155 211]]
[[148 138 158]
 [ 73  71 112]
 [181 155 211]]
[[148 138 158]
 [ 73  71 112]
 [181 155 211]]

6.3 广播 -- 重点

我们在计算的时候通常会遇到维度不一致的情况,但是这也是我们经常要使用的一种算法,故此广播就出现解决这个问题,不同大小的数组之间的运算叫做广播,如:数组与标量的算术运算会将标量值传播到各个元素。

规则1:如果俩个数组的维度数不相同,那么小维度数组的形状将会在最左边补1

规则2:如果俩个数组的形状在任何一个维度上都不匹配,那么数组的形状会沿着维度大小(元素个数)为1的维度开始扩展 ,(维度必须是1开始)直到所有维度都一样, 以匹配另一个数组的形状。

规则3:如果俩个数组的形状在任何一个维度上都不匹配,并且没有任何一个维度大小等于1,那么会引发异常。

# 规则1
import numpy as np

# 一维数组
arr1 = np.array([1,2,3]) # 形状:(3,)
# 二维数组
arr2 = np.array([[1],[2],[3]]) # 形状:(3,1)

# 对一维数组进行扩充,扩充为(1,3)[[1,2,3]]
# 此时利用规则2,在维度1的方向上进行扩充,arr1 -> (3,3) :[[1,2,3],[1,2,3],[1,2,3]] arr2 ->(3,3): [[1,1,1],[2,2,2],[3,3,3]]
print(arr1 + arr2)

[[2 3 4]
 [3 4 5]
 [4 5 6]]
# 规则三 -> 每一个维度都不一样
arr1 = np.array([1, 2, 3])  # 形状为 (3,)
arr2 = np.array([4, 5]) # 形状为 (2,)
print(arr1 + arr2)
ValueError: operands could not be broadcast together with shapes (3,) (2,) 

7. 常见函数

7.1 基本数学函数

7.1.1 计算平方根:np.sqrt(x)

作用:计算平方根

例:np.sqrt([1, 4, 9]) -> [1. 2. 3.]

import numpy as np
arr = np.random.randint(0,11,(2,3))
print(arr)
print(np.sqrt(arr))
[[5 3 7]
 [8 0 9]]
[[2.23606798 1.73205081 2.64575131]
 [2.82842712 0.         3.        ]]

7.1.2 计算指数(e^x):np.exp(x)

作用:计算指数

例:np.exp([0, 1]) [1. 2.71828183]

arr = np.random.randint(0,11,(2,3))
print(arr)
print(np.exp(arr))
[[6 9 3]
 [7 1 6]]
[[4.03428793e+02 8.10308393e+03 2.00855369e+01]
 [1.09663316e+03 2.71828183e+00 4.03428793e+02]]

7.1.3 计算自然对数(ln(x)):np.log(x)

作用:计算自然对数(ln(x))

例:np.log([1, np.e]) [0. 1.]

arr = np.random.randint(0,11,(2,3))
print(arr)
print(np.log(arr))
[[ 8  5  5]
 [ 1  4 10]]
[[2.07944154 1.60943791 1.60943791]
 [0.         1.38629436 2.30258509]]

7.1.4 计算正弦值:np.sin(x)

作用:计算正弦值

例:np.sin(x) np.sin(np.pi/2) 1.0

arr = np.array([np.pi / 4,np.pi / 3,np.pi /2 ,np.pi])
print(arr)
print(np.sin(arr))
[0.78539816 1.04719755 1.57079633 3.14159265]
[7.07106781e-01 8.66025404e-01 1.00000000e+00 1.22464680e-16]

7.1.5 计算绝对值:np.abs(x)

作用:计算绝对值

例:np.abs([-1, 2.5]) [1. 2.5]

arr = np.random.randint(-10,1,(2,3))
print(arr)
print(np.abs(arr))
[[ -9   0 -10]
 [ -5  -5 -10]]
[[ 9  0 10]
 [ 5  5 10]]

7.1.6 计算a的b次幂:np.power(a, b)

作用:计算a的b次幂

例:np.power(2, [3, 4]) -> [8 16]

print(np.power(2,3))
print(np.power([1,2,3],3))
print(np.power(2,[1,2,3]))
print(np.power(2,3))
print(np.power(2,3))
8
[ 1  8 27]
[2 4 8]
8
8

7.1.7 四舍五入:np.round(x, n)

作用:四舍五入(保留 n 位小数)

例:np.round(3.1415, 2) -> 3.14

import numpy as np
arr = np.random.uniform(0,10,(2,2))
print(arr)
arr = np.round(arr,2) # 保留两位小数
print(arr)
[[4.32896295 5.09508692]
 [1.49638811 9.53396649]]
[[4.33 5.1 ]
 [1.5  9.53]]

7.1.8 向上取整:np.ceil(x)

作用:向上取整

例:np.ceil(3.1415) -> 4.0

arr = np.random.uniform(0,10,(2,2))
print(arr)
arr = np.ceil(arr)
print(arr)
[[7.09466061 3.05790032]
 [3.20008028 1.97866083]]
4.0

7.1.9 向下取整:np.floor(x)

作用:向小取整

例:np.floor(3.1415) -> 3.0

arr = np.random.uniform(0,10,(2,2))
print(arr)
arr = np.floor(arr)
print(arr)
[[0.63374689 1.54652089]
 [1.14383778 4.69137712]]
[[0. 1.]
 [1. 4.]]

7.1.9 四舍五入到最近整数:np.rint(x)

作用:四舍五入到最近的整数,当需要舍入的数字恰好是5时,会看5前面的数字,如果是偶数则进行舍去,如果是奇数则进行进位

例:np.rint(3.1415) -> 3

np.rint(4.5) -> 4.0

np.rint(5.5) -> 6.0

arr = np.random.uniform(0,10,(2,2))
print(arr)
arr = np.rint(arr)
print(arr)
[[4.78846652 1.78595498]
 [3.32572177 8.09067695]]
[[5. 2.]
 [3. 8.]]

7.1.10 检查NaN值:np.isnan(x)

作用:检查NaN值

例:np.isnan([1,2,np.nan]) -> [False,False,True]

arr = np.array([1,2,np.nan])
print(np.isnan(arr))
[False False  True]

7.2 统计函数

7.2.1 总和(和):np.sum(x)

作用:求解总和,求解的每一个元素累计和,不论是几维度的

例:np.sum([1,2,3,4]) -> 10

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)
print(np.sum(arr))
print(np.sum(arr,axis=1))
[[ 6  3]
 [10  7]]
26
[ 9 17]

7.2.2 计算均值:np.mean(x)

作用:计算均值,未指定axis则计算是元素级别的,
axis = 1 按行算中位数

axis = 0 按列算中位数

例:np.mean([1,2,3,4]) -> 2.5

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)
print(np.mean(arr))
print(np.mean(arr,axis=1))
print(np.mean(arr,axis=0))
print(np.mean([1,2,3,4]))
[[ 6  3]
 [10  7]]
6.5
[4.5 8.5]
[8. 5.]
2.5

7.2.3 计算中位数:np.median(x)

作用:计算中位数,先排序,在计算中位数,

如果没指定axis的话,是元素级别的,即使是多维,也会压缩成一维度,在进行计算

axis = 1 按行算中位数

axis = 0 按列算中位数

例:np.median([1,2,3,4,5]) -> 3.0

print(np.median([1,2,3,4,5]))
np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)
print(np.median(arr)) 
print(np.median(arr,axis=0)) 

print(np.median(arr,axis=1))
3.0
[[ 6  3]
 [10  7]]
6.5
[8. 5.]
[4.5 8.5]

7.2.4 计算标准差:np.std(x)

标准差是什么?标准差衡量的是数据的离散程度——数据点偏离平均值的程度。简单说:标准差越大,数据越"散";标准差越小,数据越集中在平均值附近。

分三步:

算每个数据与均值的差值

把这些差值平方后求和

取平方根

作用:计算标准差

如果没指定axis的话,是元素级别的,即使是多维,也会压缩成一维度,在进行计算

axis = 1 按行算中位数

axis = 0 按列算中位数

例:np.median([1,2,3,4,5]) -> 3.0

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)

print(np.std(arr))
print(np.std(arr,axis=1))
print(np.std(arr,axis=0))

arr = np.array([5,5,5,5])
print(np.std(arr))
[[ 6  3]
 [10  7]]
2.5
[1.5 1.5]
[2. 2.]
0.0

7.2.5 计算方差:np.var(x)

方差就是标准差的平方。它同样衡量数据的离散程度,只是量纲不同。

作用:计算方差

如果没指定axis的话,是元素级别的,即使是多维,也会压缩成一维度,在进行计算

axis = 1 按行算中位数

axis = 0 按列算中位数

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)

print(np.var(arr))
print(np.var(arr,axis=1))
print(np.var(arr,axis=0))
[[ 6  3]
 [10  7]]
6.25
[2.25 2.25]
[4. 4.]

7.2.6 查找最小值:np.min(x)

作用:查找最小值

如果没指定axis的话,是元素级别的,即使是多维,也会压缩成一维度,在进行计算

axis = 1 按行算中位数

axis = 0 按列算中位数

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)

print(np.min(arr))
print(np.min(arr,axis=1))
print(np.min(arr,axis=0))
[[ 6  3]
 [10  7]]
3
[3 7]
[6 3]

7.2.7 查找最大值:np.max(x)

作用:查找最小值

如果没指定axis的话,是元素级别的,即使是多维,也会压缩成一维度,在进行计算

axis = 1 按行算中位数

axis = 0 按列算中位数

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)

print(np.max(arr))
print(np.max(arr,axis=1))
print(np.max(arr,axis=0))
[[ 6  3]
 [10  7]]
10
[ 6 10]
[10  7]

7.2.7 查找最小值索引:np.argmin(x)

作用:查找最小值索引

如果没指定axis的话,是元素级别的,即使是多维,也会压缩成一维度,在进行计算

axis = 1 按行算中位数

axis = 0 按列算中位数

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)

print(np.argmin(arr))
print(np.argmin(arr,axis=1))
print(np.argmin(arr,axis=0))
[[ 6  3]
 [10  7]]
1
[1 1]
[0 0]

7.2.7 查找最小值索引:np.argmin(x)

作用:查找最小值索引

如果没指定axis的话,是元素级别的,即使是多维,也会压缩成一维度,在进行计算

axis = 1 按行算中位数

axis = 0 按列算中位数

np.random.seed(42)
arr = np.random.randint(0,11,(2,2))
print(arr)

print(np.argmin(arr))
print(np.argmin(arr,axis=1))
print(np.argmin(arr,axis=0))
[[ 6  3]
 [10  7]]
1
[1 1]
[0 0]

7.3 比较函数

7.3.1 元素级比较a>b:np.greater(a,b)

作用:对于数组ab进行元素级比较

np.random.seed(42)
arr1 = np.random.randint(0,11,10)
arr2 = np.random.randint(0,11,10)
# 为什么设置了种子这两个数组内容不一样?
# np.random.seed(42) 不是说"以后每次 randint 都返回 42 号结果",
# 而是说"从 42 号位置开始,按顺序输出之后的随机数"。
# 这是一个确定性的伪随机序列,每次调用都会消耗掉一批随机数,
# 位置自然就变了。
print(arr1)
print(arr2)
arr3 = np.greater(arr1,arr2)
[ 6  3 10  7  4  6  9  2  6 10]
[10  7  4  3  7  7  2  5  4  1]
5

7.3.2 元素级比较a<b:np.less(a,b)

作用:对于数组a,b进行元素级比较

np.random.seed(42)
arr1 = np.random.randint(0,11,10)
arr2 = np.random.randint(0,11,10)
print(arr1)
print(arr2)
arr3 = np.less(arr1,arr2)
print(arr3)
[ 6  3 10  7  4  6  9  2  6 10]
[10  7  4  3  7  7  2  5  4  1]
[ True  True False False  True  True False  True False False]

7.3.3 元素级比较a == b:np.equal(a,b)

作用:对于数组a,b进行元素级比较

np.random.seed(42)
arr1 = np.random.randint(0,11,10)
arr2 = np.random.randint(0,11,10)
print(arr1)
print(arr2)
arr3 = np.equal(arr1,arr2)
print(arr3)
[ 6  3 10  7  4  6  9  2  6 10]
[10  7  4  3  7  7  2  5  4  1]
[False False False False False False False False False False]

7.3.4 逻辑与:np.logical_and(a,b)

作用:对于数组a,b进行逐元素逻辑与

np.random.seed(42)
arr1 = np.random.randint(0,11,15)
arr2 = np.random.randint(0,11,15)
print(arr1)
print(arr2)
arr3 = np.logical_and(arr1,arr2)
print(arr3)
[ 6  3 10  7  4  6  9  2  6 10 10  7  4  3  7]
[ 7  2  5  4  1  7  5  1  4  0  9  5  8  0 10]
[ True  True  True  True  True  True  True  True  True False  True  True
  True False  True]

7.3.5 逻辑或:np.logical_or(a,b)

作用:对于数组a,b进行逐元素逻辑或

np.random.seed(42)
arr1 = np.array([1,1,0,0])
arr2 = np.array([0,0,0,1])
print(arr1)
print(arr2)
arr3 = np.logical_or(arr1,arr2)
print(arr3)
[1 1 0 0]
[0 0 0 1]
[ True  True False  True]

7.3.6 逻辑非:np.logical_not(a)

作用:逻辑非,元素级别

np.random.seed(42)
# arr1 = np.array([1,1,0,0])
arr1 = np.random.randint(0,11,(2,2))
print(arr1)
arr2 = np.logical_not(arr1)
print(arr2)
[[ 6  3]
 [10  7]]
[[False False]
 [False False]]

7.3.7 检查数组中是否有一个元素为True:np.any(a)

注意:默认对整个数组操作,但可通过 axis 参数按轴计算

np.any([]) 返回 False(无元素满足条件)

np.random.seed(42)
arr1 = np.random.randint(0,11,(2,2))
print(arr1)
arr2 = np.any(arr1)
print(arr2)
[[ 6  3]
 [10  7]]
True

7.3.8 检查数组中是否所有元素为True:np.all(a)

注意:默认对整个数组操作,但可通过 axis 参数按轴计算

np.all([]) 返回 True

np.random.seed(42)
arr1 = np.random.randint(0,11,(2,2))
print(arr1)
arr2 = np.all(arr1)
print(arr2)
[[ 6  3]
 [10  7]]
True

7.3.9 根据条件选择元素:np.where(条件,满足条件填充,不满足条件的填充这个值)

应用场景:替换

例:

arr = np.array([1, 5, 3, 8, 2, 9])

大于5的保留原值,否则设为0

result = np.where(arr > 5, arr, 0)

print(result) # [0 0 0 8 0 9]

import numpy as np
arr = np.random.randint(0,101,10)
print(arr)
# print(np.where(arr > 60,'及格','不及格'))
# 嵌套写法
print(np.where(arr < 60,'不及格',np.where(arr<80,'良好','优秀')))
[ 91  61 100   6  49  38  14  27  53  80]
['优秀' '良好' '优秀' '不及格' '不及格' '不及格' '不及格' '不及格' '不及格' '优秀']

7.3.10 根据条件选择元素:np.select(条件列表,对应条件的填充的值)

用法:np.select(条件列表,对应条件的填充的值)

应用场景:替换

import numpy as np
arr = np.random.randint(0,101,10)
print(arr)
# 为什么写成(arr < 80) & (arr >= 60),(arr < 80 & arr >= 60)这样就不行?& 比 > < 优先级更高,会先进行80 & arr,所以用 & 组合多个条件时,每个条件必须加括号。
print(np.select([arr >= 80,(arr < 80) & (arr >= 60),arr < 60],['优秀','良好','不及格']))
[18 70  2 28 47 92 27 21  0 38]
['不及格' '良好' '不及格' '不及格' '不及格' '优秀' '不及格' '不及格' '不及格' '不及格']

7.4 排序函数

7.4.1 返回排序的副本,np.sort(x)

原地修改:x.sort()

例:np.sort([3,1,2]) -> [1,2,3]

np.random.seed(42)
arr = np.random.randint(0,11,10)
print(arr)
print(np.sort(arr))
[ 6  3 10  7  4  6  9  2  6 10]
[ 2  3  4  6  6  6  7  9 10 10]

7.4.2 返回排序的索引,np.argsort(x)

axis = 0 表示按列排序,axis = 1 表示按行排序。

例:np.argsort([3,1,2]) -> [1,2,0]

arr = [3,1,2]
print(np.argsort(arr)) # 3,1,2 -> 1,2,3 -> 1在原数组下标为1,2在原数组下标为2,3在原数组下标为0,所以是1,2,0
print(arr[1])
print(arr[2])
print(arr[0])
[1 2 0]
1
2
3

7.5 去重函数

7.5.1 返回唯一值并排序,np.unique(x)

例:np.unique([2, 1, 2, 3, 1]) [1 2 3]

arr = np.unique([2, 1, 2, 3, 1])
print(arr)
[1 2 3]

7.5.2 检查 a 的元素是否在 b 中存在,np.in1d(a, b)

例:np.in1d([1, 2, 3], [2, 4]) [False, True, False]

arr1 = [1,2,3]
arr2 = [2,4]
print(np.in1d(arr1,arr2))
[False  True False]

7.6 其他实用函数

7.6.1 数组拼接,np.concatenate((a, b))

例:np.concatenate(([1,2], [3,4])) [1, 2, 3, 4]

print(np.concatenate(([1,2], [3,4]),axis=0))
[1 2 3 4]
print(np.concatenate(([1,2], [3,4]),axis=1))
AxisError: axis 1 is out of bounds for array of dimension 1

7.6.2 分割数组,np.split(x, indices)

例:np.split([1,2,3,4], [2]) [array([1,2]), array([3,4])]

print(np.split([1,2,3,4], [3]))
[array([1, 2, 3, 4]), array([], dtype=int32)]

7.6.3 调整数组形状,np.reshape(x, shape)

np.reshape([1,2,3,4], (2,2)) [[1, 2], [3, 4]]

arr = np.reshape([1,2,3,4,5,6], (3,2))
print(arr)
[[1 2]
 [3 4]
 [5 6]]

7.6.4 调整数组形状,ndarray.flatten()

进行展平成一维数组

注意:这是ndarray的方法

import numpy as np
arr = np.array([[1,2,3,4],[2,3,4,5]])
print(arr.flatten())
[1 2 3 4 2 3 4 5]

8 综合练习

题目 1:温度数据分析
题目:某城市一周的最高气温(℃)为 [28, 30, 29, 31, 32, 30, 29]。
•计算平均气温、最高气温和最低气温。
找出气温超过 30℃ 的天数。

arr = np.array([28, 30, 29, 31, 32, 30, 29])
# 打印平均气温
print(np.mean(arr))

# 打印最高气温
print(np.max(arr))

# 打印最低气温
print(np.min(arr))

# 找出气温超过30°C的天数

print(arr[arr > 30].size) #.size是 NumPy 数组的属性,返回数组总元素个数。
print(len(arr[arr > 30])) # len()是Python 的一个内置函数,作用于 NumPy 数组时,返回其第一维的长度。
print(np.sum(np.where(arr>30,1,0)))

print(np.sum(np.greater(arr,30)))
29.857142857142858
32
28
2
2
2
2

题目 2:学生成绩统计
题目:某班级 5 名学生的数学成绩为 [85, 90, 78, 92, 88]。
•计算成绩的平均分、中位数和标准差。
将成绩转换为百分制(假设满分为 100)。

arr = np.array([85, 90, 78, 92, 88])
print("平均分",np.mean(arr))
print("中位数",np.median(arr))
print("标准差",np.std(arr))
平均分 86.6
中位数 88.0
标准差 4.882622246293481

题目 3:矩阵运算
题目:给定矩阵 A = [[1, 2], [3, 4]] 和 B = [[5, 6], [7, 8]]。
•计算 A + B 和 A * B(逐元素乘法)。
•计算 A 和 B 的矩阵乘法(点积)。

A = np.array([[1,2],[3,4]])
B = np.array([[5,6],[7,8]])
print(A + B)
print(A * B)
print(A @ B)
[[ 6  8]
 [10 12]]
[[ 5 12]
 [21 32]]
[[19 22]
 [43 50]]

题目 4:随机数据生成
题目:生成一个 (3, 4) 的随机整数数组,范围 [0, 10)。
•计算每列的最大值和每行的最小值。
•将数组中的所有奇数替换为 -1。

np.random.seed(42)
arr = np.random.randint(0,10,(3,4))
print(arr)
print(np.max(arr,axis=0))
print(np.min(arr,axis=1))
arr1 = np.where(arr % 2 == 1,-1,arr)
print(arr1)
arr[arr % 2 == 1] = -1
print(arr)
[[6 3 7 4]
 [6 9 2 6]
 [7 4 3 7]]
[7 9 7 7]
[3 2 3]
[[ 6 -1 -1  4]
 [ 6 -1  2  6]
 [-1  4 -1 -1]]
[[ 6 -1 -1  4]
 [ 6 -1  2  6]
 [-1  4 -1 -1]]

题目 5:数组变形
题目:创建一个 1 到 12 的一维数组,并转换为 (3, 4) 的二维数组。
•计算每行的和与每列的平均值。
•将数组展平为一维数组。

arr = np.arange(1,13,1)
print(arr)
arr = np.reshape(arr,(3,4))
print(arr)
print(np.sum(arr,axis=1))
print(np.mean(arr,axis=0))
print(arr.flatten())
print(np.reshape(arr,(12)))
[ 1  2  3  4  5  6  7  8  9 10 11 12]
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
[10 26 42]
[5. 6. 7. 8.]
[ 1  2  3  4  5  6  7  8  9 10 11 12]
[ 1  2  3  4  5  6  7  8  9 10 11 12]

题目 6:布尔索引
题目:生成一个 (5, 5) 的随机数组,范围 [0, 20)。
•找出数组中大于 10 的元素。不会 找出--》 布尔索引
•将所有大于 10 的元素替换为 0。 替换-》where

np.random.seed(42)
arr = np.random.randint(0,20,(5,5))
print(arr)
print(">10的元素:", arr[arr > 10]) # 这里 arr > 10 不是返回 True/False 一个值,而是 对数组里每个元素逐一比较,返回一个相同形状的布尔数组。这就是 NumPy 的向量化运算——你在第 6 节学的"元素级运算",比较运算符也适用。把布尔数组塞进 [] 里当索引,NumPy 会保留 True 位置的元素,丢弃 False 位置的元素
arr2 = np.where(arr > 10,0,arr)
print(arr2)
arr[arr > 10] = 0
print(arr)
[[ 6 19 14 10  7]
 [ 6 18 10 10  3]
 [ 7  2  1 11  5]
 [ 1  0 11 11 16]
 [ 9 15 14 14 18]]
>10的元素: [19 14 18 11 11 11 16 15 14 14 18]
[[ 6  0  0 10  7]
 [ 6  0 10 10  3]
 [ 7  2  1  0  5]
 [ 1  0  0  0  0]
 [ 9  0  0  0  0]]
[[ 6  0  0 10  7]
 [ 6  0 10 10  3]
 [ 7  2  1  0  5]
 [ 1  0  0  0  0]
 [ 9  0  0  0  0]]

题目 7:统计函数应用
题目:某公司 6 个月的销售额(万元)为 [120, 135, 110, 125, 130, 140]。
•计算销售额的总和、均值和方差。
找出销售额最高的月份和最低的月份。

arr = np.array([120, 135, 110, 125, 130, 140])
print("销售额的总和",np.sum(arr))
print("销售额的均值",np.mean(arr))
print("销售额的方差",np.var(arr))
print("最高的月份",np.argmax(arr) + 1)
print("最低的月份",np.argmin(arr) + 1)
销售额的总和 760
销售额的均值 126.66666666666667
销售额的方差 97.22222222222223
最高的月份 6
最低的月份 3

题目 8:数组拼接
题目:给定 A = [1, 2, 3] 和 B = [4, 5, 6]。
•水平拼接为 [1, 2, 3, 4, 5, 6]。
垂直拼接为 [[1, 2, 3], [4, 5, 6]]。 不会

A = np.array([1, 2, 3])
B = np.array([4, 5, 6])
print(np.concatenate((A,B)))
# 垂直拼接
print(np.vstack((A,B)))
[1 2 3 4 5 6]
[[1 2 3]
 [4 5 6]]

题目 9:唯一值与排序
题目:给定数组 [2, 1, 2, 3, 1, 4, 3]。
•找出唯一值并排序。
•计算每个唯一值出现的次数。

arr = np.array([2, 1, 2, 3, 1, 4, 3])
u_arr,counts = np.unique(arr,return_counts=True)
print(u_arr)
print(counts)
[1 2 3 4]
[2 2 2 1]

题目 10:缺失值处理
题目:给定数组 [1, np.nan, 3, np.nan, 5]。
•计算非缺失值的数量。
将缺失值替换为 0。

arr = np.array([1, np.nan, 3, np.nan, 5])
print(np.sum(~np.isnan(arr)))
arr[np.isnan(arr)] = 0;
print(arr)
3
[1. 0. 3. 0. 5.]
posted on 2026-06-10 11:39  聪明猪^(* ̄(oo) ̄)^  阅读(16)  评论(0)    收藏  举报