python - interpolación - numpy tutorial español pdf
Interpolación spline multivariante en python/scipy? (2)
¿Hay algún módulo de biblioteca u otra forma directa de implementar la interpolación de spline multivariante en python?
Específicamente, tengo un conjunto de datos escalares en una cuadrícula tridimensional regularmente espaciada que necesito interpolar en una pequeña cantidad de puntos diseminados por todo el dominio. Para dos dimensiones, he estado usando scipy.interpolate.RectBivariateSpline , y esencialmente estoy buscando una extensión de eso a datos tridimensionales.
Las rutinas de interpolación N-dimensionales que he encontrado no son lo suficientemente buenas: preferiría las splines sobre LinearNDInterpolator para suavidad, y tengo demasiados puntos de datos (a menudo más de un millón) para, por ejemplo, una función de base radial para trabajar.
Si alguien sabe de una biblioteca de Python que puede hacer esto, o tal vez una en otro idioma que yo podría llamar o puerto, realmente lo agradecería.
La interpolación de spline suave en dim> 2 es difícil de implementar, por lo que no hay muchas librerías disponibles para hacerlo (de hecho, no conozco ninguna).
Puede probar la interpolación inversa ponderada por distancia, consulte: Interpolación de distancia inversa ponderada (IDW) con Python . Esto debería producir resultados razonablemente suaves y escalar mejor que RBF a conjuntos de datos más grandes.
Si entiendo tu pregunta correctamente, ¿tus datos de "observación" de entrada se cuadran regularmente?
Si es así, scipy.ndimage.map_coordinates
hace exactamente lo que quieres.
Es un poco difícil de entender en el primer paso, pero esencialmente, solo le das una secuencia de coordenadas en la que deseas interpolar los valores de la grilla en coordenadas de píxel / vóxel / n-índice-índice.
Como un ejemplo 2D:
import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
# Note that the output interpolated coords will be the same dtype as your input
# data. If we have an array of ints, and we want floating point precision in
# the output interpolated points, we need to cast the array as floats
data = np.arange(40).reshape((8,5)).astype(np.float)
# I''m writing these as row, column pairs for clarity...
coords = np.array([[1.2, 3.5], [6.7, 2.5], [7.9, 3.5], [3.5, 3.5]])
# However, map_coordinates expects the transpose of this
coords = coords.T
# The "mode" kwarg here just controls how the boundaries are treated
# mode=''nearest'' is _not_ nearest neighbor interpolation, it just uses the
# value of the nearest cell if the point lies outside the grid. The default is
# to treat the values outside the grid as zero, which can cause some edge
# effects if you''re interpolating points near the edge
# The "order" kwarg controls the order of the splines used. The default is
# cubic splines, order=3
zi = ndimage.map_coordinates(data, coords, order=3, mode=''nearest'')
row, column = coords
nrows, ncols = data.shape
im = plt.imshow(data, interpolation=''nearest'', extent=[0, ncols, nrows, 0])
plt.colorbar(im)
plt.scatter(column, row, c=zi, vmin=data.min(), vmax=data.max())
for r, c, z in zip(row, column, zi):
plt.annotate(''%0.3f'' % z, (c,r), xytext=(-10,10), textcoords=''offset points'',
arrowprops=dict(arrowstyle=''->''), ha=''right'')
plt.show()
Para hacer esto en n-dimensions, solo tenemos que pasar las matrices de tamaño apropiado:
import numpy as np
from scipy import ndimage
data = np.arange(3*5*9).reshape((3,5,9)).astype(np.float)
coords = np.array([[1.2, 3.5, 7.8], [0.5, 0.5, 6.8]])
zi = ndimage.map_coordinates(data, coords.T)
En lo que respecta al uso de escalado y memoria, map_coordinates
creará una copia filtrada de la matriz si está utilizando una orden> 1 (es decir, no interpolación lineal). Si solo quiere interpolar en un número muy pequeño de puntos, esto es una sobrecarga bastante grande. Sin embargo, no aumenta con el número de puntos que desea interpolar. Siempre que tenga suficiente memoria RAM para una sola copia temporal de su matriz de datos de entrada, estará bien.
Si no puede almacenar una copia de sus datos en la memoria, puede a) especificar prefilter=False
y order=1
y usar interpolación lineal, ob) reemplazar sus datos originales con una versión filtrada usando ndimage.spline_filter
, y luego llamar map_coordinates con prefilter=False
.
Incluso si tiene suficiente memoria RAM, mantener el conjunto de datos filtrado puede ser una gran aceleración si necesita llamar map_coordinates varias veces (por ejemplo, uso interactivo, etc.).