Python Median Filter for 1D numpy array
Question:
I have a numpy.array
with a dimension dim_array
. I’m looking forward to obtain a median filter like scipy.signal.medfilt(data, window_len)
.
This in fact doesn’t work with numpy.array
may be because the dimension is (dim_array, 1)
and not (dim_array, )
.
How to obtain such filter?
Next, another question, how can I obtain other filter, i.e., min, max, mean?
Answers:
Based on this post
, we could create sliding windows to get a 2D
array of such windows being set as rows in it. These windows would merely be views into the data
array, so no memory consumption and thus would be pretty efficient. Then, we would simply use those ufuncs
along each row axis=1
.
Thus, for example sliding-
median` could be computed like so –
np.median(strided_app(data, window_len,1),axis=1)
For the other ufuncs
, just use the respective ufunc
names there : np.min
, np.max
& np.mean
. Please note this is meant to give a generic solution to use ufunc
supported functionality.
For the best performance, one must still look into specific functions that are built for those purposes. For the four requested functions, we have the builtins, like so –
Median : scipy.signal.medfilt
.
Max : scipy.ndimage.filters.maximum_filter1d
.
The fact that applying of a median filter with the window size 1 will not change the array gives us a freedom to apply the median filter row-wise or column-wise.
For example, this code
from scipy.ndimage import median_filter
import numpy as np
arr = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
median_filter(arr, size=3, cval=0, mode='constant')
#with cval=0, mode='constant' we set that input array is extended with zeros
#when window overlaps edges, just for visibility and ease of calculation
outputs an expected filtered with window (3, 3) array
array([[0., 2., 0.],
[2., 5., 3.],
[0., 5., 0.]])
because median_filter automatically extends the size
to all dimensions, so the same effect we can get with:
median_filter(arr, size=(3, 3), cval=0, mode='constant')
Now, we can also apply median_filter row-wise with setting 1 to the first element of size
median_filter(arr, size=(1, 3), cval=0, mode='constant')
Output:
array([[1., 2., 2.],
[4., 5., 5.],
[7., 8., 8.]])
And column-wise with the same logic
median_filter(arr, size=(3, 1), cval=0, mode='constant')
Output:
array([[1., 2., 3.],
[4., 5., 6.],
[4., 5., 6.]])
I have a numpy.array
with a dimension dim_array
. I’m looking forward to obtain a median filter like scipy.signal.medfilt(data, window_len)
.
This in fact doesn’t work with numpy.array
may be because the dimension is (dim_array, 1)
and not (dim_array, )
.
How to obtain such filter?
Next, another question, how can I obtain other filter, i.e., min, max, mean?
Based on this post
, we could create sliding windows to get a 2D
array of such windows being set as rows in it. These windows would merely be views into the data
array, so no memory consumption and thus would be pretty efficient. Then, we would simply use those ufuncs
along each row axis=1
.
Thus, for example sliding-
median` could be computed like so –
np.median(strided_app(data, window_len,1),axis=1)
For the other ufuncs
, just use the respective ufunc
names there : np.min
, np.max
& np.mean
. Please note this is meant to give a generic solution to use ufunc
supported functionality.
For the best performance, one must still look into specific functions that are built for those purposes. For the four requested functions, we have the builtins, like so –
Median : scipy.signal.medfilt
.
Max : scipy.ndimage.filters.maximum_filter1d
.
The fact that applying of a median filter with the window size 1 will not change the array gives us a freedom to apply the median filter row-wise or column-wise.
For example, this code
from scipy.ndimage import median_filter
import numpy as np
arr = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
median_filter(arr, size=3, cval=0, mode='constant')
#with cval=0, mode='constant' we set that input array is extended with zeros
#when window overlaps edges, just for visibility and ease of calculation
outputs an expected filtered with window (3, 3) array
array([[0., 2., 0.],
[2., 5., 3.],
[0., 5., 0.]])
because median_filter automatically extends the size
to all dimensions, so the same effect we can get with:
median_filter(arr, size=(3, 3), cval=0, mode='constant')
Now, we can also apply median_filter row-wise with setting 1 to the first element of size
median_filter(arr, size=(1, 3), cval=0, mode='constant')
Output:
array([[1., 2., 2.],
[4., 5., 5.],
[7., 8., 8.]])
And column-wise with the same logic
median_filter(arr, size=(3, 1), cval=0, mode='constant')
Output:
array([[1., 2., 3.],
[4., 5., 6.],
[4., 5., 6.]])