5/5 - (3票)
在Python中,numpy.gradient()
函数逼近一个N维数组的梯度。它在内部点使用二阶精确中心差分,在边界使用一阶或二阶精确单边差分进行梯度逼近。因此,返回的梯度具有与输入数组相同的形状。
下面是numpy.gradient()
的参数表。
参数 | 接受 | 参数描述 |
f | array_like | 一个包含标量函数样本的N维输入阵列。 |
varargs | 标量或数组的列表,可选 | f 值之间的间距。所有维度的默认单元间距。 |
edge_order | {1, 2} ,可选 | 梯度在边界处使用N阶实数差计算。默认:1。 |
axis | None 或 或ints的元组,可选int | 梯度只沿给定的一个或多个轴计算。默认(axis = None )是计算输入数组中所有轴的梯度。axis可能是负数,在这种情况下,它从最后一个轴算到第一个轴。 |
如果你觉得听起来不错,请继续阅读,通过PythonNumPy的代码片段和生动的视觉效果,你将充分了解numpy.gradient()
函数。
- 首先,我将介绍它的基本概念、
numpy.gradient()
语法和参数。 - 然后,你将学习这个函数的一些基本例子。
- 最后,我将解决关于
numpy.gradient()
的两个首要问题,包括np.gradient edge_order
和np.gradient axis
。
你可以在这里找到本教程的所有代码。
此外,我在另一篇关于numpy.diff()
方法的精彩指南中解释了numpy.diff()
和numpy.gradient()
的区别。
基本的概念。梯度和有限差分
对于这一部分,如果你对梯度和有限差分很熟悉,可以跳过这一部分,去看它的语法和论据!
梯度的定义。在矢量微积分中,几个变量的标量值可微调函数f的梯度是一个矢量场,其在某一点p的值是矢量,其组成部分是f在p的偏导数。
例如,下图中的蓝色箭头描述了函数f(x,y)=-(cos2x + cos2y)^2的梯度,作为底层平面上的一个投影向量场。
直观地说,你可以把梯度看作是一个点上最快增加或减少方向的指标。在计算上,梯度是一个包含某点所有偏导数的向量。
由于numpy.gradient()
函数使用有限差分来近似梯度,我们还需要了解一些有限差分的基本知识。
有限差分的定义。有限差分是一个数学表达式,其形式为f(x+b)-f(x+a)。如果有限差分除以b-a,就得到一个差分商。(维基百科)
不要惊慌!这里有我手写的一阶和二阶正向、反向和中心差分的解释和推导。这些公式是由numpy.gradient
在引擎盖下使用的。
语法和论据
这里是numpy.gradient()
的语法。
# Syntax
numpy.gradient(f[, *varargs[, axis=None[, edge_order=1]]])
这里是numpy.gradient()
的参数表。
稍后,我将更深入地讨论参数,edge_order
和axis
。
至于参数varargs
,你现在可以不使用它,当你有非单数间隔尺寸时再使用它。
numpy.gradient()
函数的输出是一个ndarrays
(如果只有一个维度,则是一个ndarray
)的列表,对应于输入f
相对于每个维度的导数。每个导数的形状与输入f
相同。
基本例子
从图片上看,这里是一个一维数组中梯度计算的说明。
下面是一个一维数组的代码例子。
import numpy as np
one_dim = np.array([1, 2, 4, 8, 16], dtype=float)
gradient = np.gradient(one_dim)
print(gradient)
'''
# * Underlying Gradient Calculation:
# Default edge_order = 1
gradient[0] = (one_dim[1] - one_dim[0])/1 = (2. - 1.)/1 = 1.
# Interior points
gradient[1] = (one_dim[2] - one_dim[0])/2 = (4. - 1.)/2 = 1.5
gradient[2] = (one_dim[3] - one_dim[1])/2 = (8. - 2.)/2 = 3.
gradient[3] = (one_dim[4] - one_dim[2])/2 = (16. - 4.)/2 = 6.
# Default edge_order = 1
gradient[4] = (one_dim[4] - one_dim[3])/1 = (16. - 8.)/1 = 8.
'''
输出。
np.gradient() edge_order
在我们的基本例子中,我们没有向numpy.gradient()
函数传递任何参数。
在本节中,我将向你展示如何部署参数edge_order
,并为边界元素设置不同的顺序差。
只是为了唤起你的记忆,这里是numpy.gradient()
的参数表。
我们可以将参数edge_order
设为1或2。它的默认值是1。
首先,我们之前的基本例子使用它的默认值1。
import numpy as np
# edge_order = 1
one_dim = np.array([1, 2, 4, 8, 16], dtype=float)
gradient = np.gradient(one_dim, edge_order=1)
print(gradient)
'''
# * Underlying Gradient Calculation:
# Default edge_order = 1
gradient[0] = (one_dim[1] - one_dim[0])/1 = (2. - 1.)/1 = 1.
# Interior points
gradient[1] = (one_dim[2] - one_dim[0])/2 = (4. - 1.)/2 = 1.5
gradient[2] = (one_dim[3] - one_dim[1])/2 = (8. - 2.)/2 = 3.
gradient[3] = (one_dim[4] - one_dim[2])/2 = (16. - 4.)/2 = 6.
# Default edge_order = 1
gradient[4] = (one_dim[4] - one_dim[3])/1 = (16. - 8.)/1 = 8.
'''
输出。
其次,我们可以将edge_order
设为2,计算边界元素的二阶差分。
import numpy as np
# edge_order = 2
one_dim = np.array([1, 2, 4, 8, 16], dtype=float)
gradient = np.gradient(one_dim, edge_order=2)
print(f'edge_order = 2 -> {gradient}')
'''
# * Underlying Gradient Calculation:
# edge_order = 2
gradient[0] = (4*one_dim[0+1] - one_dim[0+2*1] - 3*one_dim[0])/(2*1)
= (4*2. - 4. + 3*1.)/2 = 0.5
# Interior points
gradient[1] = (one_dim[2] - one_dim[0])/2 = (4. - 1.)/2 = 1.5
gradient[2] = (one_dim[3] - one_dim[1])/2 = (8. - 2.)/2 = 3.
gradient[3] = (one_dim[4] - one_dim[2])/2 = (16. - 4.)/2 = 6.
# edge_order = 2
gradient[4] = (3*one_dim[4] + one_dim[4-2*1] - 4*one_dim[4-1])/(2*1)
= (3*16. + 4. - 4*8.)/2
= 10.
'''
输出。
关于二阶正向和反向差分公式的原理,请看我之前手写的推导。我知道它们看起来确实很奇怪,但是背后有一个逻辑
np.gradient()轴
在这一部分,我将告诉你如何部署参数axis
,并通过一个2D数组的例子计算(实际上是近似)你想要的维度的梯度。
为了加深你的记忆,这里是numpy.gradient()
的参数表。
当我们有一个不止一个维度的输入时,我们可以将axis
参数设置为None
或int
或整数,以近似计算相应轴的梯度。
让我们以一个二维数组为例。
首先,让我们看看默认值,None
,会有什么作用。
import numpy as np
# axis = None (Default)
two_dim = np.array([[1, 2, 4, 8, 16],
[2, 5, 8, 10, 20]], dtype=float)
gradient = np.gradient(two_dim, axis=None)
# Same as:
# gradient = np.gradient(two_dim)
print(f'axis = None (Default): \n\n{gradient}')
print('\n', type(gradient))
输出。
我们可以看到,如果axis = None
,numpy.gradient()
函数将输出输入数组的所有轴的梯度。
在这种情况下,我们也可以向axis
参数传递一个整数。
import numpy as np
# axis = int
two_dim = np.array([[1, 2, 4, 8, 16],
[2, 5, 8, 10, 20]], dtype=float)
row_gradient = np.gradient(two_dim, axis=0)
col_gradient = np.gradient(two_dim, axis=1)
# Same as:
# row_gradient = np.gradient(two_dim, axis=-2)
# col_gradient = np.gradient(two_dim, axis=-1)
print(f'axis = 0 or -2: \n\n{row_gradient}')
print('-'*85)
print(f'axis = 1 or -1: \n\n{col_gradient}')
输出。
最后,我们可以尝试向axis
参数传递一个整数。
import numpy as np
# axis = a tuple of ints
two_dim = np.array([[1, 2, 4, 8, 16],
[2, 5, 8, 10, 20]], dtype=float)
gradient = np.gradient(two_dim, axis=[0, 1])
print(f'axis = [0,1]: \n\n{gradient}')
输出。
总结
我们的文章np.gradient()
,到此为止。
我们了解了它的基本概念、语法、参数和基本例子。
我们还研究了关于np.gradient()
函数的前两个问题,包括np.gradient edge_order
和np.gradient axis
。
希望你喜欢这一切,并祝你编码愉快!