import numpy as np
import dascore as dc
= dc.get_example_patch("example_event_2")
patch = patch.viz.waterfall()
ax "un-smoothed patch"); ax.set_title(
Patch Smoothing
This recipe compares several smoothing strategies.
A few patch methods useful for smoothing are:
Patch.rolling
is quite flexible and can be used for many different processing tasks. However, as mentioned in the rolling section of the tutorial, Patch.rolling
includes NaN
entries in the output due to edge effects. This can require some additional thought to properly deal with.
The other methods mentioned above deal with edge effects differently (governed by the mode
parameter) and by default don’t include NaN
entries.
Example Data
We will use example_event_2 to demonstrate how to use each smoothing method.
Rolling
Patch.rolling
can be used for applying aggregation functions to rolling windows along one dimension of the Patch
instance. For instance, to apply a rolling mean to the time axis:
= (
smoothed_patch =0.005).mean()
patch.rolling(time
)= smoothed_patch.viz.waterfall()
ax "rolling time mean"); ax.set_title(
or a median filter to the distance axis:
= (
smoothed_patch =20, samples=True).median()
patch.rolling(distance
)= smoothed_patch.viz.waterfall()
ax "rolling distance median"); ax.set_title(
Or both:
= (
smoothed_patch =20, samples=True).median()
patch.rolling(distance=0.005).mean()
.rolling(time
)= smoothed_patch.viz.waterfall()
ax "rolling time mean distance median"); ax.set_title(
Again though, the output array has NaN
entries along some of the edges:
= np.isnan(smoothed_patch.data)
nan_data print(f"Number of NaN = {nan_data.sum()}")
# Create and plot a patch to highlight NaN values.
= (
nan_patch =nan_data.astype(np.int32))
smoothed_patch.update(data='', data_units=None)
.update_attrs(data_type
)= nan_patch.viz.waterfall()
ax "NaNs in Patch"); ax.set_title(
Number of NaN = 47537
Which can be dropped with Patch.dropna.
[’Patch.fill_nan`]
Savgol filter
Patch.savgol_filter
uses SciPy’s savgol_filter, which is an implementation of the Savitzky-Golay Filter to apply smoothing along a single dimension.
= (
smoothed_patch =0.01, polyorder=3)
patch.savgol_filter(time
)= smoothed_patch.viz.waterfall()
ax "savgol time"); ax.set_title(
Multidimensional smoothing is achieved by applying the 1D filter sequentially along each desired dimension.
= (
smoothed_patch
patch.savgol_filter(=25,
time=25,
distance=True,
samples=2,
polyorder
)
)= smoothed_patch.viz.waterfall()
ax "savgol time and distance"); ax.set_title(
Gaussian filter
Patch.gaussian_filter
uses SciPy’s gaussian_filter to apply a gaussian smoothing operator to the patch. Note that the keyword arguments here specify standard deviation, and the truncate
keyword determines how many standard deviations are included in the smoothing kernel.
= patch.gaussian_filter(
smoothed_patch =5,
time=5,
distance=True,
samples
)= smoothed_patch.viz.waterfall()
ax "gaussian time and distance"); ax.set_title(
To visualize the smoothing kernel we can apply the operator to a patch whose data are all 0s except for a single 1 in the center.
= np.zeros_like(smoothed_patch.data)
data 0]//2, data.shape[1]//2] = 1.0
data[data.shape[
= patch.update(data=data)
delta_patch
= delta_patch.gaussian_filter(
smoothed_patch =.005,
time=15,
distance
)
= smoothed_patch.viz.waterfall()
ax "gaussian smoothing kernel"); ax.set_title(