scipyfilteringsignal-processingscipy.ndimage

How to set different stride with uniform filter in scipy?


I am using the following code to run uniform filter on my data:

from scipy.ndimage.filters import uniform_filter
a = np.arange(1000)
b = uniform_filter(a, size=10)

The filter right now semms to work as if a stride was set to size // 2. How to adjust the code so that the stride of the filter is not half of the size?


Solution

  • You seem to be misunderstanding what uniform_filter is doing.

    In this case, it creates an array b that replaces every a[i] with the mean of a block of size 10 centered at a[i]. So, something like:

    for i in range(0, len(a)):  # for the 1D case
       b[i] = mean(a[i-10//2:i+10//2]
    

    Note that this tries to access values with indices outside the range 0..1000. In the default case, uniform_filter supposes that the data before position 0 is just a reflection of the data thereafter. And similarly at the end.

    Also note that b uses the same type as a. In the example where a is of integer type, the mean will also be calculated at integer, which can cause some loss of precision.

    Here is some code and plot to illustrate what's happening:

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.ndimage.filters import uniform_filter
    
    fig, axes = plt.subplots(ncols=2, figsize=(15,4))
    
    for ax in axes:
        if ax == axes[1]:
            a = np.random.uniform(-1,1,50).cumsum()
            ax.set_title('random curve')
        else:
            a = np.arange(50, dtype=float)
            ax.set_title('values from 0 to 49')
        b = uniform_filter(a, size=10)
    
        ax.plot(a, 'b-')
        ax.plot(-np.arange(0, 10)-1, a[:10], 'b:') # show the reflection at the start
        ax.plot(50 + np.arange(0, 10), a[:-11:-1], 'b:') # show the reflection at the end
        ax.plot(b, 'r-')
    plt.show()
    

    example plot