<think>
我们正在讨论`np.linalg.norm`函数,它是NumPy中用于计算向量或矩阵范数的函数。根据引用[1]和引用[2]的内容,我们可以详细解释其用法。
### 函数功能
`np.linalg.norm(x, ord=None, axis=None, keepdims=False)`用于计算向量或矩阵的范数(长度或大小)。范数是一种度量向量或矩阵“大小”的函数,具有非负性、齐次性和三角不等式等性质。
### 参数说明
- `x`:输入数组(向量或矩阵)。
- `ord`:指定范数的类型(默认为None,即2-范数)。
- `axis`:指定沿哪个轴计算范数。对于矩阵,`axis=0`表示按列,`axis=1`表示按行。
- `keepdims`:是否保持原数组的维度。
### 常用范数类型
#### 向量范数
设向量 $\boldsymbol{x}=(x_1, x_2, \dots, x_n)$:
1. **ord=2(默认)**:2-范数(欧几里得范数)
$$
\|\boldsymbol{x}\|_2 = \sqrt{\sum_{i=1}^{n}|x_i|^2}
$$
2. **ord=1**:1-范数(曼哈顿范数)
$$
\|\boldsymbol{x}\|_1 = \sum_{i=1}^{n}|x_i|
$$
3. **ord=np.inf**:无穷范数(最大绝对值)
$$
\|\boldsymbol{x}\|_\infty = \max_{i}|x_i|
$$
4. **ord=-np.inf**:负无穷范数(最小绝对值)
$$
\|\boldsymbol{x}\|_{-\infty} = \min_{i}|x_i|
$$
5. **ord=0(非标准)**:非零元素个数(严格来说不是范数,但有时也支持)
$$
\|\boldsymbol{x}\|_0 = \sum_{i=1}^{n} \boldsymbol{1}_{x_i \neq 0}
$$
#### 矩阵范数
设矩阵 $A \in \mathbb{R}^{m \times n}$:
1. **ord='fro'**:Frobenius范数(默认矩阵范数)
$$
\|A\|_F = \sqrt{\sum_{i=1}^{m}\sum_{j=1}^{n}|a_{ij}|^2}
$$
2. **ord='nuc'**:核范数(矩阵的奇异值之和)
$$
\|A\|_* = \sum_{i=1}^{\min(m,n)} \sigma_i
$$
3. **ord=1**:列和的最大值
$$
\|A\|_1 = \max_{1 \leq j \leq n} \sum_{i=1}^{m}|a_{ij}|
$$
4. **ord=np.inf**:行和的最大值
$$
\|A\|_\infty = \max_{1 \leq i \leq m} \sum_{j=1}^{n}|a_{ij}|
$$
5. **ord=2**:谱范数(最大奇异值)
$$
\|A\|_2 = \sigma_{\max}(A)
$$
### 示例解析
根据引用[1]中的示例:
```python
import numpy as np
a = np.arange(12)
b = a.reshape((3,4))
print(np.linalg.norm(a)) # 默认ord=2,向量2-范数
print(np.linalg.norm(b)) # 默认ord=None,矩阵Frobenius范数
print(np.linalg.norm(b, 'fro')) # 同上
print(np.linalg.norm(b, 'nuc')) # 核范数
print(np.linalg.norm(a, np.inf)) # 无穷范数
print(np.linalg.norm(a, -np.inf)) # 负无穷范数
print(np.linalg.norm(a, 1)) # 1-范数
print(np.linalg.norm(b, np.inf, axis=1)) # 每行求无穷范数
print(np.linalg.norm(b, -np.inf, axis=0))# 每列求负无穷范数
print(np.linalg.norm(b, 1)) # 矩阵1-范数(列和最大值)
```
输出:
```
22.4944437584 # a的2-范数
22.4944437584 # b的Frobenius范数
22.4944437584 # 同上
24.3646384993 # b的核范数
11.0 # a的无穷范数(最大元素为11)
0.0 # a的负无穷范数(最小元素绝对值0)
66.0 # a的1-范数(0+1+...+11=66)
[ 3. 7. 11.] # 每行的无穷范数(每行最大值)
[ 0. 1. 2. 3.] # 每列的负无穷范数(每列最小值)
21.0 # 矩阵1-范数(列和最大值:列0:0+4+8=12,列1:1+5+9=15,列2:2+6+10=18,列3:3+7+11=21 → 21)
```
### 注意事项
1. 当`ord<=0`时,行为在数学上不是严格范数,但NumPy仍支持(如`ord=0`计算非零元素个数,`ord=-1`计算绝对值和倒数等)[^1]。
2. 对于复数组,范数计算使用绝对值。
3. 使用`axis`参数可沿指定轴计算,例如对矩阵每列或每行求范数。
### 应用场景
- 机器学习:正则化(L1/L2范数)[^2]
- 数值分析:矩阵条件数计算($\|A\| \cdot \|A^{-1}\|$)
- 图像处理:比较图像差异(Frobenius范数)
§§相关问题§§
1. 如何用NumPy计算矩阵的条件数?
2. L1正则化和L2正则化在机器学习中有什么区别?
3. 奇异值分解(SVD)与矩阵范数有何联系?
4. 为什么Frobenius范数在矩阵分解中常用?
</think>
### `np.linalg.norm()` 函数详解
`np.linalg.norm()` 是 NumPy 线性代数模块中的核心函数,用于计算**向量或矩阵的范数**(norm)。范数是衡量向量/矩阵"大小"的数学工具,广泛应用于机器学习、信号处理和优化问题中。
#### 一、基本语法
```python
numpy.linalg.norm(x, ord=None, axis=None, keepdims=False)
```
- **`x`**:输入数组(向量或矩阵)
- **`ord`**:范数类型(默认为 2-范数)
- **`axis`**:计算轴(针对矩阵)
- **`keepdims`**:是否保持维度
#### 二、范数类型详解
设向量 $\boldsymbol{v} = (v_1, v_2, \dots, v_n)$,矩阵 $A \in \mathbb{R}^{m \times n}$
##### 1. 向量范数
| `ord` 参数 | 数学公式 | 说明 |
|-----------|---------|------|
| `None` 或 `2` | $\|\boldsymbol{v}\|_2 = \sqrt{\sum_{i=1}^{n} |v_i|^2}$ | 欧几里得范数(默认) |
| `1` | $\|\boldsymbol{v}\|_1 = \sum_{i=1}^{n} |v_i|$ | 曼哈顿范数 |
| `np.inf` | $\|\boldsymbol{v}\|_\infty = \max(|v_i|)$ | 最大值范数 |
| `-np.inf` | $\|\boldsymbol{v}\|_{-\infty} = \min(|v_i|)$ | 最小值范数 |
| `0` | $\|\boldsymbol{v}\|_0 = \sum_{i=1}^{n} \mathbf{1}_{v_i \neq 0}$ | 非零元素计数 |
##### 2. 矩阵范数
| `ord` 参数 | 数学公式 | 说明 |
|-----------|---------|------|
| `'fro'` | $\|A\|_F = \sqrt{\sum_{i=1}^{m}\sum_{j=1}^{n} |a_{ij}|^2}$ | Frobenius 范数 |
| `'nuc'` | $\|A\|_* = \sum_{i=1}^{\min(m,n)} \sigma_i$ | 核范数(奇异值和) |
| `1` | $\|A\|_1 = \max_{1 \leq j \leq n} \sum_{i=1}^{m} |a_{ij}|$ | 列和最大值 |
| `np.inf` | $\|A\|_\infty = \max_{1 \leq i \leq m} \sum_{j=1}^{n} |a_{ij}|$ | 行和最大值 |
| `2` | $\|A\|_2 = \sigma_{\max}(A)$ | 谱范数(最大奇异值) |
#### 三、关键特性
1. **自动类型识别**:
```python
v = np.array([1, 2, 3]) # 自动识别为向量
A = np.array([[1, 2], [3, 4]]) # 自动识别为矩阵
```
2. **轴向计算**(矩阵适用):
```python
# 计算每列的 2-范数
np.linalg.norm(A, axis=0) # 输出: [3.162, 4.472]
# 计算每行的 1-范数
np.linalg.norm(A, ord=1, axis=1) # 输出: [3., 7.]
```
3. **复数支持**:
```python
c = np.array([3+4j])
np.linalg.norm(c) # 输出: 5.0 (sqrt(3²+4²))
```
#### 四、示例解析
基于引用[1][2]的代码:
```python
import numpy as np
a = np.arange(12) # [0,1,2,...,11]
b = a.reshape((3,4)) # [[0,1,2,3],[4,5,6,7],[8,9,10,11]]
print(np.linalg.norm(a)) # 输出: 22.494 (2-范数 √(0²+1²+...+11²))
print(np.linalg.norm(b)) # 同上,默认Frobenius范数
print(np.linalg.norm(b, 'fro')) # 同上
print(np.linalg.norm(b, 'nuc')) # 核范数 24.365 (奇异值和)
print(np.linalg.norm(a, np.inf)) # 11 (最大值)
print(np.linalg.norm(a, -np.inf)) # 0 (最小值)
print(np.linalg.norm(a, 1)) # 66 (绝对值求和)
print(np.linalg.norm(b, np.inf, axis=1)) # [3, 7, 11] (行最大值)
print(np.linalg.norm(b, -np.inf, axis=0)) # [0,1,2,3] (列最小值)
print(np.linalg.norm(b, 1)) # 21 (列和最大值: |0+4+8|+|1+5+9|+...)
```
#### 五、应用场景
1. **机器学习正则化**:
```python
# L2正则化项
l2_penalty = np.linalg.norm(weights)**2
```
2. **矩阵条件数计算**:
```python
cond_num = np.linalg.norm(A, 2) * np.linalg.norm(np.linalg.inv(A), 2)
```
3. **特征值分析**(结合`np.linalg.eig`[^3]):
```python
evalues, evectors = np.linalg.eig(A)
dominant_eval = np.linalg.norm(evalues, np.inf)
```
#### 六、注意事项
1. 当 `ord <= 0` 时,计算广义范数 $\|\boldsymbol{v}\|_p = \left(\sum |v_i|^p\right)^{1/p}$($p \to 0$)
2. 对大矩阵优先使用 `ord=2`(基于SVD的快速计算)
3. 空数组返回范数 0.0
> 范数是泛函分析的核心概念,在希尔伯特空间理论中有严格定义[^1][^2]。