code: def rolling_fltr(dem, f=np.nanmedian, size=3, circular=True, origmask=False):
      
      print("Applying rolling filter: %s with size %s" % (f.__name__, size))
      dem = malib.checkma(dem)
      #Convert to float32 so we can fill with nan
      dem = dem.astype(np.float32)
      newshp = (dem.size, size*size)
      #Force a step size of 1
      t = malib.sliding_window_padded(dem.filled(np.nan), (size, size), (1, 1))
      if circular:
          if size > 3:
              mask = circular_mask(size)
              t[:,mask] = np.nan
      t = t.reshape(newshp)
      out = f(t, axis=1).reshape(dem.shape)
      out = np.ma.fix_invalid(out).astype(dem.dtype)
      out.set_fill_value(dem.fill_value)
      if origmask:
          out = np.ma.array(out, mask=np.ma.getmaskarray(dem))
      return out
docs: General rolling filter (default operator is median filter)
  
      Can input any function f
  
      Efficient for smaller arrays, correclty handles NaN, fills gaps