当步长大于 1 时,用数组切片和 numpy.diff 替换 python 中的 for 循环
Replacing a for loop in python by array slicing and numpy.diff when step size is larger than 1
我想通过有限差分计算导数,但请注意,我这里的步长为 2 个网格点。
这可以在 for
循环中轻松实现,但是速度很慢。因为我正在处理 numpy
数组,所以我用数组切片替换了 for
循环以获得显着的加速。然后我想 test/compare numpy.diff
但我用它得到了不同的结果。
import matplotlib.pyplot as plt
import numpy as np
# create some data
n = 100
x = np.linspace(0,2*np.pi,n)
y = np.linspace(0,2*np.pi,n)
X,Y = np.meshgrid(x,y)
Z = np.sin(X) * np.sin(Y)
# calculate centered finite difference using for loop
Z_diff1 = Z*.0
for ii in range(1,Z.shape[0]-1,2):
for jj in range(1,Z.shape[1]-1,2):
Z_diff1[ii,jj] = Z[ii-1, jj] - Z[ii+1,jj]
# calculate centered finite difference using array slicing
Z_diff2 = Z[:-2:2,::2] - Z[2::2,::2]
# calculate centered finite difference using numpy.diff
Z_diff3 = np.diff(Z[::2,::2], axis=0)
fig = plt.figure( figsize=(8,6) )
ax1 = fig.add_subplot( 1,4,1, aspect='equal' )
ax1.pcolormesh(Z)
ax1.set_title('original data')
ax2 = fig.add_subplot( 1,4,2, aspect='equal' )
ax2.pcolormesh(Z_diff1[1::2,1::2])
ax2.set_title('for loops')
ax3 = fig.add_subplot( 1,4,3, aspect='equal' )
ax3.pcolormesh(Z_diff2)
ax3.set_title('slicing')
ax4 = fig.add_subplot( 1,4,4, aspect='equal' )
ax4.pcolormesh(Z_diff3)
ax4.set_title('numpy.diff')
plt.show()
从图中可以看出,numpy.diff
的结果看起来不同 - 我在这里遗漏了什么?
根据 docs,第一个差异由 out[i] = a[i+1] - a[i]
沿给定轴 给出。
>>> a = np.array([1, 2, 3, 4, 5, 4, 3, 2, 1])
>>> np.diff(a[::2])
array([ 2, 2, -2, -2])
你做的恰恰相反:
>>> a[:-2:2] - a[2::2]
array([-2, -2, 2, 2])
我想通过有限差分计算导数,但请注意,我这里的步长为 2 个网格点。
这可以在 for
循环中轻松实现,但是速度很慢。因为我正在处理 numpy
数组,所以我用数组切片替换了 for
循环以获得显着的加速。然后我想 test/compare numpy.diff
但我用它得到了不同的结果。
import matplotlib.pyplot as plt
import numpy as np
# create some data
n = 100
x = np.linspace(0,2*np.pi,n)
y = np.linspace(0,2*np.pi,n)
X,Y = np.meshgrid(x,y)
Z = np.sin(X) * np.sin(Y)
# calculate centered finite difference using for loop
Z_diff1 = Z*.0
for ii in range(1,Z.shape[0]-1,2):
for jj in range(1,Z.shape[1]-1,2):
Z_diff1[ii,jj] = Z[ii-1, jj] - Z[ii+1,jj]
# calculate centered finite difference using array slicing
Z_diff2 = Z[:-2:2,::2] - Z[2::2,::2]
# calculate centered finite difference using numpy.diff
Z_diff3 = np.diff(Z[::2,::2], axis=0)
fig = plt.figure( figsize=(8,6) )
ax1 = fig.add_subplot( 1,4,1, aspect='equal' )
ax1.pcolormesh(Z)
ax1.set_title('original data')
ax2 = fig.add_subplot( 1,4,2, aspect='equal' )
ax2.pcolormesh(Z_diff1[1::2,1::2])
ax2.set_title('for loops')
ax3 = fig.add_subplot( 1,4,3, aspect='equal' )
ax3.pcolormesh(Z_diff2)
ax3.set_title('slicing')
ax4 = fig.add_subplot( 1,4,4, aspect='equal' )
ax4.pcolormesh(Z_diff3)
ax4.set_title('numpy.diff')
plt.show()
从图中可以看出,numpy.diff
的结果看起来不同 - 我在这里遗漏了什么?
根据 docs,第一个差异由 out[i] = a[i+1] - a[i]
沿给定轴 给出。
>>> a = np.array([1, 2, 3, 4, 5, 4, 3, 2, 1])
>>> np.diff(a[::2])
array([ 2, 2, -2, -2])
你做的恰恰相反:
>>> a[:-2:2] - a[2::2]
array([-2, -2, 2, 2])