文章目录


前言

  在人工智能飞速发展的今天,数据早已成为驱动算法的“燃料”。不论是训练一个图像识别模型、构建一个预测系统,还是进行大规模数据分析,背后都离不开高效的数值计算能力。这也是为什么我们在学习人工智能的过程中,总是会从 NumPy 开始。
  NumPy(Numerical Python)是 Python 最基础也是最重要的科学计算库之一。它提供了一个强大且灵活的多维数组对象 ndarray,并支持向量化运算、广播机制、线性代数、随机数生成等丰富功能,这些正是现代人工智能算法的计算核心所在。
  虽然在实际项目中我们可能会使用更高级的框架如 TensorFlow、PyTorch 等进行 AI 开发,但这些框架的底层实现几乎都与 NumPy 拥有类似的张量运算逻辑。可以说,理解 NumPy,不仅能够打牢数值计算的基础,也能为日后学习深度学习和机器学习模型打下坚实的地基。
  本篇文章将作为《人工智能应用系列博文》的第一篇,带你系统了解 NumPy 的核心概念、常用操作、统计分析能力及其在 AI 中的典型应用场景。无论你是数据科学初学者,还是人工智能方向的在读研究生,相信这篇文章都能帮你从数据处理的第一步走得更稳、更扎实。


第 1 章:什么是numpy?

  NumPy(Numerical Python 的缩写)是 Python 语言中用于数值计算的核心库之一,专为处理大型多维数组与矩阵数据而设计,并提供了丰富的数学函数库来执行各种数组运算。
  如果你正在学习数据分析、机器学习或人工智能,NumPy 是你必须掌握的第一块积木。它的高性能数组对象 ndarray 提供了一个统一、高效的数据结构,可以替代 Python 原生的列表进行更快、更简洁的计算。

NumPy 的核心功能包括:
多维数组对象 ndarray:支持任意维度、任意数据类型的高效数组存储。
广播机制:可在不同形状的数组之间执行数学运算。
向量化操作:用数组代替显式循环,提升运算速度和简洁度。
线性代数、傅里叶变换、统计、随机数等数学函数库。
与 Python 生态的完美配合(如 Pandas、Matplotlib、Scikit-learn、TensorFlow 等)。


第 2 章:NumPy 基础入门

2.1 数组的创建与属性

(1)创建数组

NumPy 中最核心的数据结构是 ndarray,可以通过多种方式创建数组:

  1. np.array() 函数说明

numpy.array(object, dtype=None, copy=True, order=‘K’, subok=False, ndmin=0)

参数类型默认值说明
objectarray-like必填输入数据,可以是列表、元组、嵌套列表、其他数组对象等
dtype数据类型None指定数组中元素的数据类型,如 np.int32, np.float64, 'i2', 'f4'
copyboolTrue是否复制对象数据,若为 False 且输入已是 ndarray,可能直接返回原对象
order'K'/'C'/'F''K'内存布局:C 表示行优先(默认),F 表示列优先,K 表示与原对象一致
subokboolFalse若为 True,返回子类数组;False 时返回 base ndarray
ndminint0指定返回数组的最小维度数,常用于添加维度
  1. np.zeros() 函数说明
    创建一个指定形状、指定数据类型的数组,数组中的所有元素都初始化为 0。

numpy.zeros(shape, dtype=float, order=‘C’)

参数类型默认值说明
shapeint 或 tuple of int必填指定数组的形状,例如 3 表示一维长度为 3,(2, 3) 表示 2 行 3 列
dtype数据类型float数组中元素的数据类型,如 np.int32np.float64
order'C''F''C'数组的内存布局:'C' 表示按行存储(C风格),'F' 表示按列存储(Fortran风格)
  1. np.ones() 函数说明
    创建一个指定形状的数组,所有元素初始化为 1。

numpy.ones(shape, dtype=None, order=‘C’)

参数类型默认值说明
shapeint 或 tuple of int必填指定数组形状,例如 3 表示长度为 3 的一维数组,(2, 3) 表示 2 行 3 列
dtype数据类型None元素数据类型,如 np.int32np.float64 等,默认推断为 float64
order'C''F''C'数组内存布局:'C' 为行优先,'F' 为列优先
  1. np.arange() 函数说明
    生成一个从 start 到 stop(不包含)的等差数列数组。

numpy.arange([start,] stop[, step], dtype=None)

参数类型默认值说明
start数值0起始值,默认从 0 开始
stop数值必填结束值(不包含)
step数值1步长,指定数值之间的间隔
dtype数据类型None输出数组元素的数据类型,默认自动推断
  1. np.arange() 函数说明
    生成一个从 start 到 stop(不包含)的等差数列数组。

numpy.arange([start,] stop[, step], dtype=None)

参数类型默认值说明
start数值0起始值,默认从 0 开始
stop数值必填结束值(不包含)
step数值1步长,指定数值之间的间隔
dtype数据类型None输出数组元素的数据类型,默认自动推断
  1. np.linspace() 函数说明
    在线性区间 [start, stop] 上生成 num 个均匀间隔的数值数组。

numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0)

参数类型默认值说明
start数值必填起始值
stop数值必填结束值
numint50要生成的样本数量
endpointboolTrue是否包含终点值 stop
retstepboolFalse若为 True,返回间隔值 step 与数组
dtype数据类型None输出数组数据类型,默认自动推断
axisint0放置样本的轴(适用于多维数组生成)

示例

import numpy as np

# 从列表创建数组
a = np.array([1, 2, 3])

# 创建全 0 数组
b = np.zeros((2, 3))

# 创建全 1 数组
c = np.ones((3, 3))

# 创建等差数组
d = np.arange(0, 10, 2)  # [0 2 4 6 8]

# 创建等间隔数值
e = np.linspace(0, 1, 5)  # [0.   0.25 0.5  0.75 1.  ]

# 创建随机数组
f = np.random.rand(2, 2)

你可以根据需求选择不同的方式生成初始化数据,尤其在神经网络初始化权重时经常用到 np.random 系列函数。
我们可以使用jupyter notebook按步进行学习
在这里插入图片描述

(2)查看数组属性

NumPy 数组对象拥有多个属性,帮助我们理解数据结构和维度信息:

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

print("数组维度数 ndim:", arr.ndim)         # 2
print("数组形状 shape:", arr.shape)         # (2, 3)
print("数组元素总数 size:", arr.size)       # 6
print("数组数据类型 dtype:", arr.dtype)     # int64
print("每个元素字节数 itemsize:", arr.itemsize)  # 8

在这里插入图片描述

属性含义
ndim数组的维度数
shape数组的形状(各轴大小)
size元素总数
dtype每个元素的数据类型
itemsize单个元素占用的字节数

这些属性对于调试维度不匹配问题、进行广播运算和矩阵变换非常有用。

2.2 数据类型与类型转换

(1)数据类型

类型描述示例代码简写
bool_布尔类型(True 或 False)np.bool_?
int88 位有符号整数(-128 到 127)np.int8i1
int1616 位有符号整数np.int16i2
int3232 位有符号整数np.int32i4
int6464 位有符号整数np.int64i8
uint88 位无符号整数(0 到 255)np.uint8u1
uint1616 位无符号整数np.uint16u2
uint3232 位无符号整数np.uint32u4
uint6464 位无符号整数np.uint64u8
float1616 位浮点数(半精度)np.float16f2
float3232 位浮点数(单精度)np.float32f4
float6464 位浮点数(双精度,默认)np.float64f8
complex64复数(两个 float32)np.complex64c8
complex128复数(两个 float64)np.complex128c16
str_Unicode 字符串(定长)np.str_U + 字符长度
bytes_字节串(定长)np.bytes_S + 字节长度
object_任意 Python 对象(性能较低)np.object_O

(2)数据类型的操作

  1. 指定创建数组数据类型
a = np.array([1,0,1,0],dtype=np.bool)	#或者使用dtype='?'
print(a)
print("数组数据类型 dtype:", a.dtype)

在这里插入图片描述

  1. 修改数组数据类型

ndarray.astype() 函数说明
a.astype() 是 NumPy 中用于将数组 a 的元素转换为指定数据类型的方法。它会返回一个新的数组,原始数组不会被修改。这是处理模型输入、内存压缩、图像处理、类型安全等场景中非常常用的方法。

new_array = a.astype(dtype, order=‘K’, casting=‘unsafe’, subok=True, copy=True)

参数类型默认值说明
dtypestr 或类型必填要转换成的目标数据类型,如 'int32', np.float64, 'f2', 'u1'
order'C', 'F', 'A', 'K''K'内存布局:C 表示行优先,F 表示列优先,K 表示尽量保持原布局
casting'no', 'equiv', 'safe', 'same_kind', 'unsafe''unsafe'控制是否允许不同类型间的强制转换
subokboolTrue是否允许子类返回,True 则保留原始子类
copyboolTrue是否始终返回新数组(即使类型相同)
a.astype("i1") #或者使用a.astype(np.int8)
print(a)
print("数组数据类型 dtype:", a.dtype)

在这里插入图片描述
注意:我们可以发现数据类型并没有被更改掉,这是 NumPy 中非常重要的一个行为特性:astype() 不会修改原数组,而是返回一个新数组
也就是说:

a_int = a.astype("i1")
print(a_int)
print("数组数据类型 dtype:", a_int.dtype)

返回的是新的 int8 类型数组,原数组 a 的类型保持不变。
在这里插入图片描述

  1. 修改浮点数的小数位数

np.round() 函数说明
np.round() 用于对数组中的每个元素进行四舍五入操作。你可以指定保留的小数位数(默认为整数),常用于模型预测结果处理、数值展示、数据归一化后的格式化输出等场景。

numpy.round(a, decimals=0, out=None)

参数类型默认值说明
aarray-like必需输入数组或数值,支持 Python 数、列表、ndarray 等
decimalsint0保留的小数位数。正数表示保留的小数位,负数表示四舍五入到十位、百位等
outndarrayNone可选输出数组,用于存放结果,节省内存
arr = np.random.rand(2, 5)
print(arr)
arr = np.round(arr,2)
print(arr)

在这里插入图片描述

2.3 数组形状操作

(1) 查看数组情况

arr = np.array([[3,4,5,6,7,8],[4,5,6,7,8,9]])
print("数组形状 shape:", arr.shape)

在这里插入图片描述

(2) 修改数组形状

函数名作用是否修改原数组是否返回新数组支持维度自动推导 -1报错条件
reshape()返回一个新形状的数组,不改变原数组❌ 否✅ 是✅ 支持元素数量不匹配时报错
resize()直接修改原数组形状✅ 是❌ 否(原地操作)❌ 不支持元素不足会补零,过多则截断
a = np.array([1, 2, 3, 4, 5, 6])

# reshape
b = a.reshape((2, 3))
# b: [[1 2 3]
#     [4 5 6]]

# resize
a.resize((3, 2))
# a: [[1 2]
#     [3 4]
#     [5 6]]

(3) 数组扁平化

函数名作用是否复制数据是否修改原数组返回值类型
flatten()返回复制后的扁平数组✅ 是❌ 否一维 ndarray
ravel()返回视图或复制(尽量视图)❌ 视图优先❌ 否一维 ndarray
a = np.array([[1, 2], [3, 4]])

# flatten
b = a.flatten()
b[0] = 100
# a 不变

# ravel
c = a.ravel()
c[0] = 200
# a 被修改

(4) 维度扩展与压缩

函数名作用说明
expand_dims()在指定位置插入新轴(增加维度)可用于从 (3,) 变为 (1, 3)(3, 1)
squeeze()移除数组中维度为 1 的维度常用于去除多余维度,如从 (1, 3, 1) 变为 (3,)
a = np.array([1, 2, 3])

# expand_dims
b = np.expand_dims(a, axis=0)  # shape: (1, 3)
c = np.expand_dims(a, axis=1)  # shape: (3, 1)

# squeeze
d = np.array([[[1], [2], [3]]])  # shape: (1, 3, 1)
e = np.squeeze(d)                # shape: (3,)

第 3 章:数组运算与广播机制

3.1 数组运算

(1) 加法减法

NumPy 支持数组与数值(标量)之间的逐元素运算:

import numpy as np

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

print(arr + 5)  # [6 7 8]
print(arr - 1)  # [0 1 2]

说明:每个元素都执行相同的加减操作

(2) 乘法除法

arr = np.array([2, 4, 6])

print(arr * 2)    # [ 4  8 12]
print(arr / 2)    # [1. 2. 3.]

说明:输出结果中如果涉及除法,NumPy 会自动转换为 float 类型。

(3) 数组和数组的加减法

数组之间可以直接进行逐元素的加减运算(要求形状一致或可广播):

a = np.array([1, 2, 3])
b = np.array([10, 20, 30])

print(a + b)  # [11 22 33]
print(b - a)  # [9 18 27]

(4) 数组和数组的乘除法

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

print(a * b)  # [4 10 18]  ← 逐元素乘法(不是矩阵乘法)
print(b / a)  # [4.0 2.5 2.0]

注意:这不是矩阵乘法,是逐元素乘法,称为 element-wise operation。

如果你想进行矩阵乘法,请使用:

np.dot(a, b)       # 向量点积
a @ b              # Python 3.5+ 支持的矩阵乘号

(5) 不同维度的数组计算(广播机制)

NumPy 的 广播(broadcasting)机制 允许不同形状的数组自动对齐进行运算。
广播原则:如果两个数组的后缘维度(trailing dimension,即从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失和长度为1的维度上进行。

广播规则总结

  • 如果两个数组的维度数不同,较小维度的数组会在最左边自动补 1。
  • 若某个维度不匹配但其中一个是 1,可以广播。
  • 否则报错:ValueError: operands could not be broadcast together
类型操作示例
数组 + 标量加/减a + 1, a * 10
数组 + 数组(形状一致)加/减/乘/除a + b, a * b
数组 + 数组(可广播)自动扩展A + b(维度不同时广播)
向量点积点积np.dot(a, b)a @ b
矩阵乘法多维乘法A @ Bnp.matmul(A, B)

示例 1:1D 和 2D 相加

A = np.array([[1, 2, 3],
              [4, 5, 6]])
B = np.array([10, 20, 30])

print(A + B)
# 输出:
# [[11 22 33]
#  [14 25 36]]

示例 2:列向量与矩阵相加

A = np.array([[1, 2, 3],
              [4, 5, 6]])
B = np.array([[10],
              [20]])

print(A + B)
# 输出:
# [[11 12 13]
#  [24 25 26]]

3.2 关于轴(axis)的补充说明

在 NumPy 中,axis 表示 沿着哪个维度进行操作
axis=0沿着第 0 维(即跨行),操作的是
axis=1沿着第 1 维(即跨列),操作的是
axis=2:在 3D 数组中,表示跨页(最里层元素)

维度数组形状可选 axis 值含义简述
1D 向量(n,)0对整个向量进行操作
2D 矩阵(m, n)0 或 10:跨行(列间聚合)
1:跨列(行间聚合)
3D 张量(a, b, c)0 / 1 / 20:跨块;1:跨行;2:跨列
  1. 二维数组的轴
    在这里插入图片描述

  2. 三维数组的轴
    在这里插入图片描述

3.3 条件逻辑处理

方法作用用法示例
np.where()条件选择(类似三元运算)np.where(x > 0, x, 0)
clip()限制最小最大值np.clip(data, min_value, max_value)

(1)np.where() — 三元选择(条件表达式)

numpy.where(condition, x, y)
相当于:x if condition else y(逐元素判断)

参数说明
condition条件数组,结果为 True 的位置将选取 x 的值
x满足条件的位置所采用的值
y不满足条件的位置所采用的值
import numpy as np

a = np.array([10, 20, 30, 40])
b = np.array([1, 2, 3, 4])

# 如果 a > 25,则取 a,否则取 b
result = np.where(a > 25, a, b)
print(result)
# 输出: [ 1  2 30 40]

也可以只传 condition,返回满足条件的元素索引:

indices = np.where(a > 25)
print(indices)
# 输出: (array([2, 3]),)

(2)clip() — 限制数值范围

numpy.clip(array, min, max)
将数组中所有小于min的值变为min,大于max的变为max,中间值保持不变。
用途

  • 限制数据范围(如图像灰度值限制在 0~255)
  • 防止异常值干扰分析
a = np.array([1, 5, 10, 15, 20])

# 将所有值限制在 [5, 15] 之间
clipped = np.clip(a, 5, 15)
print(clipped)
# 输出: [ 5  5 10 15 15]

第 4 章:数组索引与切片技巧

  在人工智能项目中,我们经常需要对数组中的部分数据进行访问、修改、筛选。NumPy 提供了强大而灵活的索引与切片机制,使得对多维数组的操作变得简洁高效。

4.1 基本索引与切片

(1) 基本索引

类似 Python 的列表语法,NumPy 支持:

  • 使用索引访问单个元素
  • 使用冒号 : 对数组进行切片
  • 支持多维数组的索引
表达式含义示例输出
a[i]i[5 6 7 8]
a[:, j]j[3 7 11]
a[i:j]i 到第 j-1[[5 6 7 8], [9 10 11 12]]
a[:, j:k]所有行的第 j 到第 k-1[[3 4], [7 8], [11 12]]
a = np.array([[1, 2, 3, 4],
			  [5, 6, 7, 8],
              [9, 10, 11, 12]])

print(a[1])	#取一行
print(a[:,2])	#取一列
print(a[1:3])	#取多行
print(a[:,2:4])	#取多行

在这里插入图片描述

(2) 切片(Slicing)

array[start:stop:step]

  • start:起始索引(包含)
  • stop:终止索引(不包含)
  • step:步长(可选)
arr = np.arange(10)  # [0 1 2 3 4 5 6 7 8 9]

print(arr[2:7])      # [2 3 4 5 6]
print(arr[::2])      # [0 2 4 6 8]
print(arr[::-1])     # [9 8 7 6 5 4 3 2 1 0] → 反转

(3) 二维数组切片

可以同时对行、列进行切片。

a = np.array([[11, 12, 13],
              [21, 22, 23],
              [31, 32, 33]])

print(a[0:2, 1:3])

说明:

  • 取第 0~1 行、第 1~2 列
  • 行是前两个,列是最后两列

4.2 高级索引

(1) 布尔索引(Boolean Indexing)

a = np.array([10, 20, 30, 40, 50])
mask = a > 25

print(mask)     # [False False  True  True  True]
print(a[mask])  # [30 40 50]

#也可简写成
print(a[a > 25])  # [30 40 50]

(2) 花式索引(Fancy Indexing)

使用整数列表或数组作为索引来访问多个非连续元素。

a = np.array([10, 20, 30, 40, 50])
idx = [1, 3, 4]

print(a[idx])  # [20 40 50]

二维数组也支持:

b = np.array([[1, 2], [3, 4], [5, 6]])
rows = [0, 2]
cols = [1, 0]

print(b[rows, cols])  # [2, 5]

4.3 注意事项

(1) 修改切片视图 vs 复制

切片得到的是视图(View),修改切片会影响原数组!

a = np.arange(6)
b = a[2:5]
b[0] = 99

print(a)  # [0 1 99 3 4 5]

如果希望独立修改,需要用.copy()

b = a[2:5].copy()

(2) 多维数组取整列 / 整行

a = np.array([[10, 20, 30],
              [40, 50, 60]])

print(a[:, 0])  # 所有行的第 0 列 → [10 40]
print(a[1, :])  # 第 1 行的所有列 → [40 50 60]

小结

类型说明示例
基本索引单个元素访问a[1, 2]
切片连续子集访问a[1:3, 0:2]
步长切片跳跃取值或反转a[::-1]
布尔索引通过条件表达式筛选a[a > 10]
花式索引通过索引数组访问非连续元素a[[1, 3, 5]]
切片是视图修改切片会影响原数组a[2:4] = ...

第 5 章:数组结构操作进阶

5.1 转置与轴交换

(1)转置的基本概念

  转置是指交换数组的轴(维度),对于numpy中的数组来说,就是在对角线方向交换数据,最常见的是 二维数组的行列互换:如果有一个形状为 (m, n) 的数组,转置后变成 (n, m)。

(2) .T 属性:快速二维转置

import numpy as np

a = np.array([[1, 2],
              [3, 4],
              [5, 6]])

print("原数组形状:", a.shape)   # (3, 2)
print("转置后形状:", a.T.shape)  # (2, 3)
print(a.T)

在这里插入图片描述

(3) np.transpose() 函数:通用多维转置

  numpy.transpose() 是用于 交换数组的维度顺序(轴) 的函数。它适用于任意维度的数组,能够实现灵活的张量转置操作,是多维数组处理和深度学习数据预处理的重要工具。

numpy.transpose(a, axes=None)

参数说明

  • a:输入数组(可以是 1D、2D、3D 或更高维)
  • axes:指定新的维度顺序,是一个元组或列表(默认是反转所有轴)
a = np.array([[1, 2], [3, 4], [5, 6]])
print(np.transpose(a))  # 或 a.T

在这里插入图片描述

(4) .swapaxes()

  numpy.swapaxes()用于 交换数组中的两个轴(维度)。它是 np.transpose() 的简化形式,专门用于仅交换两个轴,而不是对所有轴重新排序。

np.swapaxes(a, axis1, axis2)
a.swapaxes(axis1, axis2)

参数说明

  • a:输入的数组
  • axis1、axis2:要交换的两个轴的编号(从 0 开始)
a = np.array([[1, 2], [3, 4], [5, 6]])
print(a.swapaxes(1, 0))  # 或 a.T

在这里插入图片描述

(5) 二维 vs 多维数组转置差异总结

操作适用于功能
.T2D、3D 等默认反转所有轴(例如 2D 行列互换)
np.transpose()任意维度数组显式指定维度顺序
np.swapaxes()任意维度数组仅交换指定的两个轴

(6) 常见使用场景

应用场景示例
矩阵行列转置a.T
图像维度转换(HWC → CHW)np.transpose(img, (2, 0, 1))
批量数据转置(batch_size, time_steps, features)(time_steps, batch_size, features)
RNN 数据准备PyTorch 中常将输入维度调换以适配模型

5.2 数组合并与分割

(1)np.concatenate()

沿指定轴拼接数组

np.concatenate((a1, a2, …), axis=0)

参数说明
a1, a2需要拼接的数组序列,形状需匹配(除了拼接轴)
axis沿哪个轴拼接,默认是 0
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])

result = np.concatenate((a, b), axis=0)
print(result)
# 输出:
# [[1 2]
#  [3 4]
#  [5 6]]

(2)np.stack()

沿新轴堆叠数组

np.stack((a1, a2, …), axis=0)

参数说明
a1, a2数组形状必须完全一致
axis堆叠时创建的新轴位置

concatenate不同的是,stack增加一个新维度。

a = np.array([1, 2])
b = np.array([3, 4])

result = np.stack((a, b), axis=0)
print(result)
# 输出:
# [[1 2]
#  [3 4]]

result = np.stack((a, b), axis=1)
print(result)
# 输出:
# [[1 3]
#  [2 4]]

(3)np.split()

将数组拆分成多个子数组

np.split(array, indices_or_sections, axis=0)

参数说明
array被拆分的数组
indices_or_sections拆分方式,可以是整数或索引列表
axis沿哪个轴进行拆分
  • 如果是整数n,则平均分成n份(必须能整除)
  • 如果是列表[i1, i2],则在指定索引处分段

示例:整数拆分

#你这段代码的作用是将二维数组 a 沿 行方向(axis=0) 平均分成 2 个子数组。
a = np.array([[1, 2], [3, 4], [5, 6], [7, 8]])
parts = np.split(a, 2, axis=0)
for p in parts:
    print(p)

输出:

[[1 2]
 [3 4]]
[[5 6]
 [7 8]]

示例:索引拆分

#分割点索引 [2, 4] 表示:
#第一个子数组:a[0:2] = [1, 2]
#第二个子数组:a[2:4] = [3, 4]
#第三个子数组:a[4:] = [5, 6]

a = np.array([1, 2, 3, 4, 5, 6])
parts = np.split(a, [2, 4])
print(parts)  # 输出: [array([1, 2]), array([3, 4]), array([5, 6])]

总结

函数名功能是否增加维度备注说明
concatenate沿已有轴拼接维度不变,拼接前维度需兼容
stack沿新轴堆叠会新增一个维度
split沿指定轴拆分平均拆分或在索引处分段

5.3 排序

(1)np.sort()

排序(返回排序后的数组)

np.sort(a, axis=-1)

参数说明
a要排序的数组
axis指定排序的轴,默认按行排序(最后一维)

示例:

a = np.array([[3, 1, 2], [6, 4, 5]])
sorted_a = np.sort(a, axis=1)
print(sorted_a)

输出:

[[1 2 3]
 [4 5 6]]

(2)np.argsort()

返回排序后元素的索引

np.argsort(a, axis=-1)

返回的是排序后元素在原数组中的索引位置,常用于间接排序或提取 top-N 元素。

示例:

a = np.array([3, 1, 2])
index = np.argsort(a)
print(index)         # [1 2 0]
print(a[index])      # [1 2 3]

二维数组示例:

a = np.array([[8, 2, 3], [4, 7, 6]])
idx = np.argsort(a, axis=1)
print(idx)

输出:

[[1 2 0]
 [0 2 1]]

总结

方法功能结果类型说明
.T / transpose()行列互换数组维度调换
sort()排序(返回排序后值)排序后的新数组不改变原数组(除非指定 in-place)
argsort()排序(返回索引)排序后索引数组可用于间接排序

第 6 章:常用统计分析函数

6.1 均值、中位数、标准差、方差

函数功能示例
np.mean()求平均值np.mean(a)
np.median()求中位数np.median(a)
np.std()求标准差np.std(a)
np.var()求方差np.var(a)

可使用axis参数指定按行或按列:

import numpy as np

# 一维数组
a = np.array([1, 2, 3, 4, 5, 6])

print("一维数组:", a)
print("均值 mean:", np.mean(a))        # 输出: 3.5
print("中位数 median:", np.median(a))  # 输出: 3.5
print("标准差 std:", np.std(a))        # 输出: 1.707...
print("方差 var:", np.var(a))          # 输出: 2.916...

6.2 最大最小值与对应索引

函数功能
np.max()最大值
np.min()最小值
np.argmax()最大值对应索引
np.argmin()最小值对应索引
a = np.array([1, 7, 3, 9, 5])

print(np.max(a))        # 9
print(np.argmax(a))     # 3(索引为 3 的位置是最大值 9)

print(np.min(a))        # 1
print(np.argmin(a))     # 0

二维数组可以加axis参数:

a = np.array([[1, 3, 2], [6, 5, 4]])
print(np.argmax(a, axis=1))  # 每行最大值的索引:[1 0]

6.3 缺失值处理技巧(NaN)

当数组中包含np.nan时,普通统计函数如np.mean()会返回nan,这时需要使用带nan前缀的函数进行处理。

函数功能
np.nanmean()忽略 NaN 求均值
np.nanstd()忽略 NaN 求标准差
np.nanvar()忽略 NaN 求方差
np.nanmin()忽略 NaN 求最小值
np.nanmax()忽略 NaN 求最大值

示例:

import numpy as np

# 创建包含 NaN 的数组
a = np.array([1, 2, np.nan, 4, 5])
print("原始数组:", a)

mean_val = np.nanmean(a)
print("忽略 NaN 的均值:", mean_val)	#

std_val = np.nanstd(a)
print("忽略 NaN 的标准差:", std_val)

var_val = np.nanvar(a)
print("忽略 NaN 的方差:", var_val)

min_val = np.nanmin(a)
print("忽略 NaN 的最小值:", min_val)

max_val = np.nanmax(a)
print("忽略 NaN 的最大值:", max_val)

结果:


原始数组: [ 1.  2. nan  4.  5.]
忽略 NaN 的均值: 3.0
忽略 NaN 的标准差: 1.5811388300841898
忽略 NaN 的方差: 2.5
忽略 NaN 的最小值: 1.0
忽略 NaN 的最大值: 5.0

判断和处理缺失值:

np.isnan(a)               # 返回布尔数组:标识哪些是 NaN
a[np.isnan(a)] = 0        # 将 NaN 替换为 0

6.4 总结

功能标准函数忽略 NaN 函数
均值np.mean()np.nanmean()
中位数np.median()np.nanmedian()
标准差np.std()np.nanstd()
方差np.var()np.nanvar()
最大值np.max()np.nanmax()
最小值np.min()np.nanmin()

第 7 章:随机数与概率分布

7.1 基础随机数函数

函数说明示例结果
np.random.rand(d0, d1, ...)生成 [0, 1) 范围内的均匀分布随机数np.random.rand(2,3)
np.random.randint(low, high, size)生成指定整数范围的随机整数np.random.randint(1, 10, size=5)
np.random.choice(a, size)从一维数组中随机选取元素(可重复/不重复)np.random.choice([1,2,3], 5)

示例:

import numpy as np

print("rand:", np.random.rand(2, 3))       # 生成 2x3 的[0,1)均匀分布随机数
print("randint:", np.random.randint(5, 10, size=4))  # 生成4个[5,10)间整数
print("choice:", np.random.choice([10, 20, 30], size=5))  # 从数组中随机选

7.2 常见概率分布

(1)正态分布(高斯分布)

正态分布,也称为高斯分布,是一种连续概率分布,广泛用于自然科学、工程、金融建模等领域。其概率密度函数(PDF)为:
在这里插入图片描述

符号含义
μ \mu μ均值(位置中心)
σ \sigma σ标准差(控制分布的宽度)
σ 2 \sigma^2 σ2方差

在这里插入图片描述

np.random.normal(loc=0.0, scale=1.0, size=None)

参数说明
loc均值 μ
scale标准差 σ
size输出样本形状
samples = np.random.normal(loc=0, scale=1, size=1000)

(2)均匀分布(Uniform Distribution)

均匀分布是最简单、最基本的一种概率分布。它描述了在一定范围内,各个数值出现的概率相等。
在这里插入图片描述

np.random.uniform(low=0.0, high=1.0, size=None)

  • 生成 [low, high) 区间内的随机样本
samples = np.random.uniform(5, 10, size=5)
print(samples)

(3)泊松分布(Poisson Distribution)

在这里插入图片描述

假设某事件在单位时间(或单位空间)内平均发生次数为𝜆>0,则事件在该单位时间内恰好发生𝑘次的概率为:
在这里插入图片描述

  • 𝜆是事件的平均发生率(均值)
  • 𝑘是事件发生的具体次数(非负整数)

np.random.poisson(lam=λ, size=None)

  • 模拟事件在单位时间/空间内发生的次数(如服务器访问、电话呼叫)
samples = np.random.poisson(lam=5, size=10)
print(samples)

(4)其他分布(了解)

分布类型函数应用场景举例
二项分布np.random.binomial(n, p, size)抛硬币 n 次成功次数
指数分布np.random.exponential(scale, size)模拟等待时间
β 分布np.random.beta(a, b, size)概率分布建模(贝叶斯)
γ 分布np.random.gamma(shape, scale, size)服务时间建模

总结

函数类型函数名描述
均匀分布rand(), uniform()均匀分布
正态分布normal()高斯分布
整数随机randint()指定范围内的整数
随机采样choice()从数组中随机采样
泊松分布poisson()模拟单位时间的事件次数
二项分布binomial()成功/失败型实验(伯努利试验)
指数分布exponential()模拟等待时间

第 8 章:数据读写操作

  在实际人工智能项目或数据分析工作中,最常见的操作之一就是从本地磁盘或网络加载数据。NumPy 提供了多种读取文本、CSV、二进制等格式的函数,使用方便、高效。

8.1 NumPy 支持的常见数据格式

(1)文本文件(Text)
特点

  • 数据以纯文本形式存储
  • 可以用 空格、逗号、**制表符(Tab)**等作为分隔符
  • 常见扩展名:.txt、.dat

优点

  • 易于查看、编辑、跨平台
  • 可用 Excel、记事本等工具打开

缺点

  • 文件体积较大
  • 加载速度慢于二进制格式
  • 只能表示简单数值,不支持复杂结构

NumPy 函数

  • np.loadtxt():用于读取标准格式的数值文本
  • np.genfromtxt():更宽容,支持缺失值和混合数据

(2)CSV 文件(Comma-Separated Values)

特点

  • 逗号分隔的文本格式
  • 常用于 Excel 导出、表格型数据
  • 扩展名通常是 .csv

优点

  • 通用性强,是很多数据平台的导入导出标准格式
  • 一行一条记录,结构清晰
  • 方便与 pandas 配合使用(pd.read_csv())

缺点

  • 与文本文件类似,纯文本不支持高效随机访问
  • 字符串数据或缺失值需要特别处理

NumPy 函数

  • 同样使用 np.loadtxt() 或 np.genfromtxt(),指定 delimiter=‘,’

(3)二进制文件(NumPy 自有格式)
.npy 与 .npz 格式
这是NumPy 专属的高性能存储格式,推荐用于 AI 项目中的中间数据或模型缓存。

  • .npy:用于保存单个数组
  • .npz:用于保存多个数组(字典形式)

优点

  • 读取速度快,效率高(可用于大数据集)
  • 保存数据结构完整(包括 dtype、shape)
  • 可与 PyTorch、TensorFlow 等无缝集成

缺点

  • 只能被 NumPy 加载,不适合数据共享给其他语言
  • 不可读性强(是二进制文件)

NumPy 函数

  • np.save() / np.savez()
  • np.load():读取 .npy 或 .npz
格式文件类型可读性压缩性速度跨平台通用性NumPy读取方式
.txt文本✅ 高❌ 无❌ 慢loadtxt() / genfromtxt()
.csv文本(逗号)✅ 高❌ 无❌ 慢loadtxt() / genfromtxt()
.npy二进制❌ 无✅ 高✅ 快⛔ 仅限 Pythonsave() / load()
.npz二进制(多数组)❌ 无✅ 高✅ 快⛔ 仅限 Pythonsavez() / load()

8.2 np.loadtxt() — 读取文本/CSV 文件

numpy.loadtxt() 是 NumPy 中用于从文本文件中快速读取纯数值数据的函数,适合读取 .txt、.csv 等结构简单、格式统一的文件。
适用于绝大多数AI 项目的数据预加载阶段,如图像特征、标签、向量等。

numpy.loadtxt(fname, dtype=float, delimiter=None, skiprows=0, usecols=None, encoding=‘bytes’)

参数说明:

参数类型说明
fnamestr 或文件对象要读取的文件路径
dtype数据类型默认 float,可设置为 intstr
delimiter字符串指定列之间的分隔符,如 ',''\t'
skiprows整数跳过文件开头的几行(常用于跳过标题)
usecols元组/列表指定读取的列(索引从 0 开始)
encoding字符串文件编码,如 'utf-8'(推荐)
import numpy as np

data = np.loadtxt('data.txt', delimiter=',')
print(data)

参数说明

参数含义
fname文件路径(字符串)
delimiter分隔符,如,\t空格
dtype数据类型(默认 float
skiprows跳过前几行
usecols指定读取哪些列(索引)
encoding字符编码(推荐 utf-8

示例:读取csv文件

data = np.loadtxt('iris.csv', delimiter=',', usecols=(0, 1), skiprows=1)

8.3 np.genfromtxt() — 更强大的读取器

numpy.genfromtxt() 是一个功能更强大的数据读取函数,专用于读取结构复杂的文本数据,包括:

  • 含有缺失值的表格
  • 混合数据类型(数值 + 字符串)
  • 有列名/表头的 CSV 文件等

可看作是 np.loadtxt() 的增强版本,适合处理实际 AI 项目中非标准化的数据集。

numpy.genfromtxt(fname,
dtype=float,
delimiter=None,
names=False,
skip_header=0,
usecols=None,
missing_values=None,
filling_values=None,
encoding=‘bytes’)

参数说明:

参数类型说明
fname字符串/文件对象文件路径或打开的文件对象
dtype数据类型/结构化类型数据类型(可为 float, str, 或复合类型)
delimiter字符串分隔符,如 ',''\t'
names布尔/字符串列表是否读取第一行为字段名,或手动指定字段名
skip_header整数跳过的开头行数
usecols元组/列表读取指定的列(列索引)
missing_values字符/列表表示缺失值的字符串,如 "NA""?"
filling_values单个值/列表用于替换缺失值的默认值
encoding字符串文件编码,推荐 'utf-8'

它比loadtxt()更宽容,可以处理缺失值、混合数据等情况。

data = np.genfromtxt('data.csv', delimiter=',', skip_header=1)

特点

  • 支持 missing_values 与 filling_values
  • 自动跳过缺失或不规则格式行
  • 可读取字符串列(配合 dtype=None)

8.4 np.load() — 读取 .npy 或 .npz 文件(二进制)

numpy.load() 是用于从磁盘读取 NumPy 的二进制文件格式(.npy 和 .npz)的函数。相比文本文件,它具有更高的读取速度和更好的结构信息保存能力,适合用于中间数据缓存、模型处理、AI 项目数据存储等场景。

numpy.load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, encoding=‘ASCII’)

参数说明:

参数说明
file文件路径或类文件对象
mmap_mode是否使用内存映射读取文件,可设为 'r' 只读
allow_pickle是否允许加载对象(如果使用了 pickle 存储)
fix_imports是否兼容 Python 2 的导入路径(不常用)
encoding加载 pickle 对象时的编码(通常设为 'utf-8'

NumPy 专有的高效格式,适合保存大规模数组/模型中间结果:

# 保存数组
np.save('array.npy', my_array)

# 读取数组
arr = np.load('array.npy')
# 保存多个数组
np.savez('data.npz', a=arr1, b=arr2)

# 读取
data = np.load('data.npz')
print(data['a'])  # 访问 a

8.5 读取路径说明(相对/绝对)

  • 'data/data.csv':相对路径,当前项目目录下的 data 文件夹
  • 'C:/Users/xxx/Desktop/file.csv':绝对路径(Windows)
  • r'C:\path\to\file.csv':使用 原始字符串 规避反斜杠转义问题

8.6 处理中文路径(Windows)

如果路径中含有中文,建议加上 encoding='utf-8'

data = np.loadtxt('数据文件.csv', delimiter=',', encoding='utf-8')

8.7 小结:常用数据读取函数对比

函数功能描述支持缺失值可读字符串列推荐用途
loadtxt()快速读取纯数字文本整洁数值表格
genfromtxt()读取带缺失值或复杂结构的文本CSV、混合数据
load()读取 .npy / .npz 二进制文件模型中间数据存取

第 9 章:实用技巧与性能建议

9.1 拷贝 vs 视图(复制 vs 引用)

在 NumPy 中,大部分操作默认返回视图(View)而非拷贝(Copy),这能提升性能,但容易出错。
在这里插入图片描述
示例:

import numpy as np

a = np.array([1, 2, 3])
b = a          # 共享内存
c = a.copy()   # 深拷贝

a[0] = 99
print("b:", b)  # 输出 b: [99  2  3](和 a 同变)
print("c:", c)  # 输出 c: [1  2  3](独立副本)
操作是否拷贝是否共享内存
a[1:3]
a.copy()
reshape()是(如果连续)
np.array(a)否(强拷贝)

9.2 避免 Python 循环:使用向量化计算(Vectorization)

NumPy 的最大优势之一是用向量化操作代替 for 循环,更快更简洁。
低效做法(for 循环)

a = np.arange(1000000)
b = np.zeros_like(a)
for i in range(len(a)):
    b[i] = a[i] * 2

高效做法(向量化)

b = a * 2

结果相同,速度差别可达几十倍甚至上百倍!

9.3 性能测试工具

(1)%timeit测时间

IPythonJupyter中可使用:

import numpy as np
a = np.arange(1000000)

%timeit a * 2

(2)memory_profiler测内存

安装:

pip install memory_profiler

使用示例(在.py脚本中):

from memory_profiler import profile

@profile
def test():
    a = [i**2 for i in range(1000000)]
    return a

test()

运行脚本时:

python -m memory_profiler yourscript.py
技巧类别建议
内存拷贝.copy() 显式深拷贝
数组切片默认视图,避免误修改原数组
性能优化避免 for 循环,使用广播/向量化
评估工具%timeit 测时、memory_profiler 测内存

第 10 章:numpy与人工智能的关系

  人工智能中的许多核心操作——如矩阵乘法、激活函数、梯度更新、权重初始化等——都离不开大规模的数组和矩阵运算。现代深度学习框架(如 TensorFlow 和 PyTorch)底层实现与 NumPy 十分接近,甚至在早期版本中直接使用了 NumPy 结构。所以,掌握 NumPy,不仅是写出高效 Python 程序的基础,更是深入理解 AI 框架背后原理的关键。

NumPy 在 AI 中的作用说明
数值计算基础高效处理向量、矩阵,是 AI 的数学地基
深度学习框架兼容接口几乎所有 AI 框架都支持或使用 NumPy
数据预处理从图像、文本到结构化数据,处理都依赖 NumPy
教学和原型验证工具许多 AI 教材和实验用纯 NumPy 写小模型验证

后续文章预告

下一篇:《【人工智能】(二)人工智能应用入门:从 Pandas 开始掌握数据分析》

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐