JAV
JAV

Reputation: 308

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?

Upvotes: 0

Views: 1036

Answers (1)

JohanC
JohanC

Reputation: 80319

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

Upvotes: 1

Related Questions