numpy.gradient#
- numpy.gradient(f, *varargs, axis=None, edge_order=1)[source]#
傳回 N 維陣列的梯度。
梯度是使用內部點的二階精確中心差分,以及邊界處的一階或二階精確單邊(前向或後向)差分計算的。因此,傳回的梯度與輸入陣列具有相同的形狀。
- 參數:
- f類陣列
包含純量函數樣本的 N 維陣列。
- varargs純量或陣列列表,選用
f 值之間的間距。所有維度的預設單位間距。間距可以使用以下方式指定
單一純量以指定所有維度的樣本距離。
N 個純量以指定每個維度的常數樣本距離。例如 dx、dy、dz、…
N 個陣列以指定 F 沿每個維度的值的座標。陣列的長度必須符合對應維度的大小
N 個純量/陣列的任意組合,含義如 2. 和 3.
如果給定 axis,varargs 的數量必須等於軸的數量。預設值:1。(請參閱以下範例)。
- edge_order{1, 2},選用
梯度是使用邊界處的 N 階精確差分計算的。預設值:1。
- axisNone 或 int 或 int 元組,選用
梯度僅沿給定的軸或軸計算。預設值 (axis = None) 是計算輸入陣列所有軸的梯度。軸可以是負數,在這種情況下,它從最後一個軸數到第一個軸。
- 傳回值:
- gradientndarray 或 ndarray 元組
一個 ndarray 元組(或如果只有一個維度,則為單個 ndarray),對應於 f 對每個維度的導數。每個導數的形狀都與 f 相同。
註解
假設 \(f\in C^{3}\) (即,\(f\) 至少有 3 個連續導數),並令 \(h_{*}\) 為非均勻步長,我們最小化「一致性誤差」\(\eta_{i}\),即真實梯度與其從相鄰網格點的線性組合的估計之間
\[\eta_{i} = f_{i}^{\left(1\right)} - \left[ \alpha f\left(x_{i}\right) + \beta f\left(x_{i} + h_{d}\right) + \gamma f\left(x_{i}-h_{s}\right) \right]\]通過將 \(f(x_{i} + h_{d})\) 和 \(f(x_{i} - h_{s})\) 替換為它們的泰勒級數展開式,這轉化為求解以下線性系統
\[\begin{split}\left\{ \begin{array}{r} \alpha+\beta+\gamma=0 \\ \beta h_{d}-\gamma h_{s}=1 \\ \beta h_{d}^{2}+\gamma h_{s}^{2}=0 \end{array} \right.\end{split}\]\(f_{i}^{(1)}\) 的結果近似值如下
\[\hat f_{i}^{(1)} = \frac{ h_{s}^{2}f\left(x_{i} + h_{d}\right) + \left(h_{d}^{2} - h_{s}^{2}\right)f\left(x_{i}\right) - h_{d}^{2}f\left(x_{i}-h_{s}\right)} { h_{s}h_{d}\left(h_{d} + h_{s}\right)} + \mathcal{O}\left(\frac{h_{d}h_{s}^{2} + h_{s}h_{d}^{2}}{h_{d} + h_{s}}\right)\]值得注意的是,如果 \(h_{s}=h_{d}\) (即,資料均勻間隔),我們找到標準的二階近似值
\[\hat f_{i}^{(1)}= \frac{f\left(x_{i+1}\right) - f\left(x_{i-1}\right)}{2h} + \mathcal{O}\left(h^{2}\right)\]使用類似的程序,可以推導出用於邊界的前向/後向近似值。
參考文獻
[1]Quarteroni A.、Sacco R.、Saleri F. (2007) Numerical Mathematics (Texts in Applied Mathematics)。紐約:Springer。
[2]Durran D. R. (1999) Numerical Methods for Wave Equations in Geophysical Fluid Dynamics。紐約:Springer。
[3]Fornberg B. (1988) Generation of Finite Difference Formulas on Arbitrarily Spaced Grids, Mathematics of Computation 51, no. 184 : 699-706。 PDF。
範例
>>> import numpy as np >>> f = np.array([1, 2, 4, 7, 11, 16]) >>> np.gradient(f) array([1. , 1.5, 2.5, 3.5, 4.5, 5. ]) >>> np.gradient(f, 2) array([0.5 , 0.75, 1.25, 1.75, 2.25, 2.5 ])
間距也可以使用陣列指定,該陣列表示值 F 沿維度的座標。例如均勻間距
>>> x = np.arange(f.size) >>> np.gradient(f, x) array([1. , 1.5, 2.5, 3.5, 4.5, 5. ])
或非均勻間距
>>> x = np.array([0., 1., 1.5, 3.5, 4., 6.]) >>> np.gradient(f, x) array([1. , 3. , 3.5, 6.7, 6.9, 2.5])
對於二維陣列,傳回值將是按軸排序的兩個陣列。在此範例中,第一個陣列代表行中的梯度,第二個陣列代表列方向中的梯度
>>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]])) (array([[ 2., 2., -1.], [ 2., 2., -1.]]), array([[1. , 2.5, 4. ], [1. , 1. , 1. ]]))
在此範例中,間距也已指定:axis=0 為均勻間距,axis=1 為非均勻間距
>>> dx = 2. >>> y = [1., 1.5, 3.5] >>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]]), dx, y) (array([[ 1. , 1. , -0.5], [ 1. , 1. , -0.5]]), array([[2. , 2. , 2. ], [2. , 1.7, 0.5]]))
可以使用 edge_order 指定如何處理邊界
>>> x = np.array([0, 1, 2, 3, 4]) >>> f = x**2 >>> np.gradient(f, edge_order=1) array([1., 2., 4., 6., 7.]) >>> np.gradient(f, edge_order=2) array([0., 2., 4., 6., 8.])
axis 關鍵字可用於指定要計算梯度的軸的子集
>>> np.gradient(np.array([[1, 2, 6], [3, 4, 5]]), axis=0) array([[ 2., 2., -1.], [ 2., 2., -1.]])
varargs 參數定義輸入陣列中樣本點之間的間距。它可以採用兩種形式
一個陣列,指定座標,座標可能不均勻間隔
>>> x = np.array([0., 2., 3., 6., 8.]) >>> y = x ** 2 >>> np.gradient(y, x, edge_order=2) array([ 0., 4., 6., 12., 16.])
一個純量,代表固定的樣本距離
>>> dx = 2 >>> x = np.array([0., 2., 4., 6., 8.]) >>> y = x ** 2 >>> np.gradient(y, dx, edge_order=2) array([ 0., 4., 8., 12., 16.])
可以為沿每個維度的間距提供不同的資料。參數的數量必須與輸入資料中的維度數量相符。
>>> dx = 2 >>> dy = 3 >>> x = np.arange(0, 6, dx) >>> y = np.arange(0, 9, dy) >>> xs, ys = np.meshgrid(x, y) >>> zs = xs + 2 * ys >>> np.gradient(zs, dy, dx) # Passing two scalars (array([[2., 2., 2.], [2., 2., 2.], [2., 2., 2.]]), array([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]))
也允許混合使用純量和陣列
>>> np.gradient(zs, y, dx) # Passing one array and one scalar (array([[2., 2., 2.], [2., 2., 2.], [2., 2., 2.]]), array([[1., 1., 1.], [1., 1., 1.], [1., 1., 1.]]))