numpy.gradient用于计算离散数组的数值梯度,默认中心差分(边界用单侧差分),结果与输入同形;支持多维、指定步长和轴向,但仅适用于已知数值点,不接受函数表达式。

用 numpy.gradient 计算离散数组的数值梯度
numpy.gradient 是 NumPy 中最直接、最常用的数值梯度计算函数,适用于一维到多维规则网格上的数组。它默认使用中心差分(两端用前/后向差分),结果与输入数组形状一致。
常见错误是传入非等距坐标或误以为它能处理任意函数表达式——它只对已知数值点有效,不接受 callable 或符号表达式。
- 一维场景:给定
y = np.array([0, 1, 4, 9, 16])(即 x² 在 x=[0,1,2,3,4] 的取值),调用np.gradient(y)得到近似导数 [1., 2., 4., 6., 7.] - 指定步长:若 x 坐标非单位间隔,比如
x = np.array([0, 0.5, 1.5, 2.5, 4.0]),应写成np.gradient(y, x),否则默认按索引差 1 计算,结果严重失真 - 二维数组:对图像灰度矩阵
img,np.gradient(img)返回两个数组,分别对应 y 和 x 方向的梯度(注意顺序:先 axis=0,再 axis=1)
手动实现前向/中心差分时要注意步长和边界
当需要控制差分方式(如强制前向差分)、或处理不规则采样点时,手写更可靠。但容易忽略两点:除以真实 Δx 而非 Δindex,以及边界点如何处理。
例如,对函数 f(x)=sin(x) 在 x=[0, 0.1, 0.3, 0.6, 1.0] 上采样:
import numpy as np x = np.array([0, 0.1, 0.3, 0.6, 1.0]) y = np.sin(x) # 错误:直接 np.diff(y) / np.diff(np.arange(len(y))) # 正确:必须用真实的 x 间距 dx = np.diff(x) dy_dx = np.diff(y) / dx # shape (4,), 对应区间中点导数
若需与原数组等长,可补一个值(如重复末值)或改用中心差分插值,但无通用最优法——得看下游用途是否容忍边界偏移。
对比 scipy.misc.derivative 和 numpy.gradient 的适用场景
scipy.misc.derivative(注意:SciPy 1.10+ 已移至 scipy.optimize.approx_fprime 或推荐用 scipy.misc.derivative 的替代接口)面向的是「给定函数 f 和某点 x₀,求该点导数值」;而 numpy.gradient 面向的是「给定一批离散 y 值,求每个点附近的变化率」。
- 如果你有闭式函数(如
lambda x: x**2 * np.exp(-x)),且只需在几个特定点求导,用scipy.misc.derivative(f, x0, dx=1e-6) - 如果你读取了传感器时间序列
data.npy,想画出整个信号的瞬时变化率曲线,必须用numpy.gradient,不能先造函数再调用 scipy - 性能上:
numpy.gradient是纯向量化 C 实现,比反复调用scipy.misc.derivative快 100 倍以上
高阶导数与精度陷阱
numpy.gradient 不支持直接计算二阶导数;多次调用会快速放大噪声和边界误差。比如对含噪声的信号做两次 np.gradient,高频扰动会被显著增强。
真正需要二阶导时,更稳妥的做法是:先用平滑(如 scipy.ndimage.gaussian_filter1d)再求梯度,或改用拟合后求导(如用 numpy.polynomial.Polynomial.fit 拟合三阶多项式,再调用 .deriv(2))。
另外,numpy.gradient 默认用一阶精度差分;若数据质量高且网格均匀,可自己用五点 stencil 手写二阶精度中心差分,但多数场景没必要——先确认噪声是不是主要误差源。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











