Suite

Reconstruire les séries temporelles MODIS en appliquant le filtre Savitzky-Golay avec Python/Numpy


Je souhaite appliquer le filtre « Savitzky-Golay » (savgol) à ma série chronologique, ensemble de données MODIS, pour supprimer le bruit (c'est-à-dire les pixels de nuage, etc.) dans mes données. MODIS a des indicateurs de qualité qui indiquent la fiabilité de chaque valeur de pixel ou si le pixel est éventuellement affecté par des nuages. Je voudrais donc incorporer ces indicateurs de qualité dans mon filtre en mettant moins de poids ou en ignorant ces valeurs de pixel et en laissant le filtre savgol prédire la valeur de pixel optimale. je testenp.NaN/np.nan/est nulmais il semble qu'il supprime l'élément du tableau et, par conséquent, le filtre savgol ignore également ces valeurs. Je voudrais que mes données résultantes soient comme dans la figure ci-jointe.

(https://matinbrandt.wordpress.com/2014/12/02/smoothingfiltering-a-ndvi-time-series-using-a-savitzky-golay-filter-and-r/)


Vous devez interpoler les données manquantes avant de pouvoir appliquer le filtre Savitzky-Golay. TIMESAT est l'outil le plus largement utilisé pour ce travail et ils traitent les données manquantes avec une interpolation linéaire avant d'appliquer le filtre Savitzky-Golay. En supposant que vous ayez déjà masqué les observations nuageuses et autres mauvaises commenp.nanvoici comment interpoler une série chronologique avec pandas.interpoler() puis appliquer le filtre Savitzky-Golay scipy.signal.savgol_filter().

importer numpy en tant que np importer des pandas en tant que pd de scipy.signal importer savgol_filter #créer une série temporelle aléatoire time_series = np.random.random(50) time_series[time_series < 0.1] = np.nan time_series = pd.Series(time_series) # interpoler données manquantes time_series_interp = time_series.interpolate(method="linear") # appliquer le filtre SavGol time_series_savgol = savgol_filter(time_series_interp, window_length=7, polyorder=2)

Il existe bien sûr d'autres moyens d'interpoler les données manquantes, mais pandas est l'un des moyens les plus pratiques de le faire, surtout si vous souhaitez tester les effets de différents algorithmes d'interpolation.


Basé sur le filtre SG descipy.signalJ'ai construit l'algorithme de lissage des séries temporelles NDVI proposé dans :

Une méthode simple pour reconstruire un ensemble de données de séries chronologiques NDVI de haute qualité basé sur le filtre Savitzky-Golay", Jin Chen et al. 2004

importer des pandas en tant que pd importer numpy en tant que np de scipy.signal importer savgol_filter def savitzky_golay_filtering(timeseries, wnds=[11, 7], orders=[2, 4], debug=True): interp_ts = pd.Series(timeseries) interp_ts = interp_ts.interpolate(method='linear', limit=14) smooth_ts = interp_ts wnd, order = wnds[0], orders[0] F = 1e8 W = None it = 0 while True: smoother_ts = savgol_filter(smooth_ts, window_length= wnd, polyorder=order) diff = smoother_ts - interp_ts sign = diff > 0 si W est Aucun : W = 1 - np.abs(diff) / np.max(np.abs(diff)) * signe wnd, order = wnds [1], commandes[1] ajustement_score = np.sum(np.abs(diff) * W) l'imprime, ' : ', ajustement_score si ajustement_score > F: break else: F = ajustement_score it += 1 smooth_ts = smoother_ts * signe + interp_ts * (1 - signe) si débogage : renvoie smooth_ts, interp_ts renvoie smooth_ts

Vous êtes sur la bonne voie, veuillez lire l'article que j'ai mis dans les commentaires de votre question.

Un organigramme avec les étapes à suivre à partir de ce document (au cas où vous n'y auriez pas accès) :

Comme vous pouvez le voir, pour l'étape 1, vous supprimeriez les nuages ​​de la série chronologique ; puis appliquer des techniques d'interpolation pour combler les lacunes.

Une méthode serait comme Chen et al. suggèrent une interpolation linéaire, avec les méthodes décrites par Kersten, dans sa réponse.


Voir la vidéo: MetPy Mondays #88 - Savitzky-Golay (Octobre 2021).