pyyeti.dsp.exclusive_sgfilter

pyyeti.dsp.exclusive_sgfilter(x, n, exclude_point='first', axis=-1)[source]

1-d moving average that excludes selected point

More specifically, this is a 0th order 1-d Savitzky-Golay FIR filter that has been modified such that it excludes the selected point. This is helpful to find outliers.

Parameters:
  • x (nd array_like) – Array to filter

  • n (odd integer) – Number of points for filter; if even, it is reset to n+1

  • exclude_point (string or int or None; optional) – Defines which point to exclude in each moving average window. If integer, it must be in [0, n), specifying the point to exclude. If string, it must be ‘first’, ‘middle’, or ‘last’ (which is the same as 0, n // 2, and n-1, respectively). If None, no point will be excluded (this is primarily for testing and should match a standard 0th order Savitzky-Golay filter).

  • axis (integer; optional) – Axis along which to apply filter; each subarray along this axis is filtered. For example, to filter each column in a 2d array, set axis to 0.

Returns:

x_f (nd ndarray) – Filtered version of x

Notes

The end windows cannot all exclude the selected point. For example, if the excluded point is the first point in each window, the last n-1 windows cannot follow this rule. To illustrate, let signal x be np.arange(9), n be 5, and exclude_point be ‘first’ (or 0). In this scenario, the last 4 windows cannot exclude the first point (the “-” denotes the excluded point for each window):

     x = [0, 1, 2, 3, 4, 5, 6, 7, 8]

1st ave:  -  +  +  +  +
2nd ave:     -  +  +  +  +
3rd ave:        -  +  +  +  +
4th ave:           -  +  +  +  +
5th ave:              -  +  +  +  +
6th ave:              +  -  +  +  +
7th ave:              +  +  -  +  +
8th ave:              +  +  +  -  +
9th ave:              +  +  +  +  -

If exclude_point is ‘middle’ or n // 2:

     x = [0, 1, 2, 3, 4, 5, 6, 7, 8]

1st ave:  -  +  +  +  +
2nd ave:  +  -  +  +  +
3rd ave:  +  +  -  +  +
4th ave:     +  +  -  +  +
5th ave:        +  +  -  +  +
6th ave:           +  +  -  +  +
7th ave:              +  +  -  +  +
8th ave:              +  +  +  -  +
9th ave:              +  +  +  +  -

If exclude_point is ‘last’ or n-1:

     x = [0, 1, 2, 3, 4, 5, 6, 7, 8]

1st ave:  -  +  +  +  +
2nd ave:  +  -  +  +  +
3rd ave:  +  +  -  +  +
4th ave:  +  +  +  -  +
5th ave:  +  +  +  +  -
6th ave:     +  +  +  +  -
7th ave:        +  +  +  +  -
8th ave:           +  +  +  +  -
9th ave:              +  +  +  +  -

Examples

>>> import numpy as np
>>> from pyyeti.dsp import exclusive_sgfilter
>>> x = np.arange(6.)
>>> x[3] *= 2
>>> x
array([ 0.,  1.,  2.,  6.,  4.,  5.])
>>> for point in ('first', 'middle', 'last'):
...     print(exclusive_sgfilter(x, 3, exclude_point=point))
[ 1.5  4.   5.   4.5  5.5  5. ]
[ 1.5  1.   3.5  3.   5.5  5. ]
[ 1.5  1.   0.5  1.5  4.   5. ]

Equivalent run using indexes:

>>> for point in (0, 1, 2):
...     print(exclusive_sgfilter(x, 3, exclude_point=point))
[ 1.5  4.   5.   4.5  5.5  5. ]
[ 1.5  1.   3.5  3.   5.5  5. ]
[ 1.5  1.   0.5  1.5  4.   5. ]

If exclude_point is None, this is the same as a normal 0th order Savitzky-Golay filter:

>>> from scipy.signal import savgol_filter
>>> savgol_filter(x, 3, polyorder=0)
array([ 1.,  1.,  3.,  4.,  5.,  5.])
>>> exclusive_sgfilter(x, 3, exclude_point=None)
array([ 1.,  1.,  3.,  4.,  5.,  5.])