Reemplazando un bucle for en Python por la selección de un arreglo y numpy.diff cuando el tamaño del paso es mayor a 1.
Quiero calcular la derivada mediante diferencias finitas, ten en cuenta que aquí tengo un tamaño de paso de 2 puntos en la cuadrícula.
Esto se puede realizar fácilmente en un bucle “for”, pero es bastante lento. Dado que estoy trabajando con arreglos de “numpy”, reemplacé el bucle “for” por un corte de arreglos para obtener una mejora significativa en la velocidad. Luego, quería probar/comparar “numpy.diff”, pero obtengo un resultado diferente al usarlo.
import matplotlib.pyplot as plt
import numpy as np
# crear algunos datos
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)
# calcular la diferencia finita centrada usando un bucle "for"
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]
# calcular la diferencia finita centrada usando el corte de arreglos
Z_diff2 = Z[:-2:2, ::2] - Z[2::2, ::2]
# calcular la diferencia finita centrada usando np.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('datos originales')
ax2 = fig.add_subplot(1, 4, 2, aspect='equal')
ax2.pcolormesh(Z_diff1[1::2, 1::2])
ax2.set_title('bucles "for"')
ax3 = fig.add_subplot(1, 4, 3, aspect='equal')
ax3.pcolormesh(Z_diff2)
ax3.set_title('corte de arreglos')
ax4 = fig.add_subplot(1, 4, 4, aspect='equal')
ax4.pcolormesh(Z_diff3)
ax4.set_title('numpy.diff')
plt.show()
Como se puede ver en la figura, el resultado de “numpy.diff” se ve diferente. ¿Qué me estoy perdiendo aquí?
davy.ai
La principal diferencia entre el método de división de
numpy
ynumpy.diff
es quenumpy.diff
calcula la diferencia hacia adelante entre elementos adyacentes. En este caso,numpy.diff
calcula la diferencia entre(Z[0,0], Z[0,1], Z[0,2], ...)
,(Z[1,0], Z[1,1], Z[1,2], ...)
, y así sucesivamente. Sin embargo, la diferencia centrada deseada se calcula tomando los valores anteriores y siguientes dos valores, como se puede ver en el buclefor
y el método de división. Por lo tanto, usarnumpy.diff
con un tamaño de paso de 2 no da el resultado deseado.