@@ -223,18 +223,29 @@ def extract_ids(self, tracks):
223
223
224
224
def extract_with_length (self , bounds ):
225
225
b0 , b1 = bounds
226
- if b0 >= 0 and b1 >= 0 :
226
+ if b0 >= 0 and b1 >= 0 :
227
227
track_mask = (self .nb_obs_by_track >= b0 ) * (self .nb_obs_by_track <= b1 )
228
228
elif b0 < 0 and b1 >= 0 :
229
229
track_mask = self .nb_obs_by_track <= b1
230
230
elif b0 >= 0 and b1 < 0 :
231
231
track_mask = self .nb_obs_by_track > b0
232
232
else :
233
- logging .warning (' No valid value for bounds' )
234
- raise Exception (' One bounds must be positiv' )
233
+ logging .warning (" No valid value for bounds" )
234
+ raise Exception (" One bounds must be positiv" )
235
235
return self .__extract_with_mask (track_mask .repeat (self .nb_obs_by_track ))
236
236
237
- def __extract_with_mask (self , mask , full_path = False , remove_incomplete = False , compress_id = False ):
237
+ def loess_filter (self , window , xfield , yfield , inplace = True ):
238
+ track = self .obs ["track" ]
239
+ x = self .obs [xfield ]
240
+ y = self .obs [yfield ]
241
+ window = window
242
+ result = track_loess_filter (window , x , y , track )
243
+ if inplace :
244
+ self .obs [yfield ] = result
245
+
246
+ def __extract_with_mask (
247
+ self , mask , full_path = False , remove_incomplete = False , compress_id = False
248
+ ):
238
249
"""
239
250
Extract a subset of observations
240
251
Args:
@@ -297,4 +308,46 @@ def compute_index(tracks, index, number):
297
308
@njit (cache = True )
298
309
def compute_mask_from_id (tracks , first_index , number_of_obs , mask ):
299
310
for track in tracks :
300
- mask [first_index [track ]:first_index [track ] + number_of_obs [track ]] = True
311
+ mask [first_index [track ] : first_index [track ] + number_of_obs [track ]] = True
312
+
313
+
314
+ @njit (cache = True )
315
+ def track_loess_filter (window , x , y , track ):
316
+ """
317
+ Apply a loess filter on y field
318
+ Args:
319
+ window: parameter of smoother
320
+ x: must be growing for each track but could be irregular
321
+ y: field to smooth
322
+ track: field which allow to separate path
323
+
324
+ Returns:
325
+
326
+ """
327
+ nb = y .shape [0 ]
328
+ last = nb - 1
329
+ y_new = empty (y .shape , dtype = y .dtype )
330
+ for i in range (nb ):
331
+ cur_track = track [i ]
332
+ y_sum = y [i ]
333
+ w_sum = 1
334
+ if i != 0 :
335
+ i_previous = i - 1
336
+ dx = x [i ] - x [i_previous ]
337
+ while dx < window and i_previous != 0 and cur_track == track [i_previous ]:
338
+ w = (1 - (dx / window ) ** 3 ) ** 3
339
+ y_sum += y [i_previous ] * w
340
+ w_sum += w
341
+ i_previous -= 1
342
+ dx = x [i ] - x [i_previous ]
343
+ if i != last :
344
+ i_next = i + 1
345
+ dx = x [i_next ] - x [i ]
346
+ while dx < window and i_next != last and cur_track == track [i_next ]:
347
+ w = (1 - (dx / window ) ** 3 ) ** 3
348
+ y_sum += y [i_next ] * w
349
+ w_sum += w
350
+ i_next += 1
351
+ dx = x [i_next ] - x [i ]
352
+ y_new [i ] = y_sum / w_sum
353
+ return y_new
0 commit comments