2

I'm trying to perform a "running max-min window" on a numpy array, such that for a given window size, the function returns the distance between the maximum and minimum values for this window.

I would also like to determine the length of each "skip" of the window.

For example:

if x_array = np.array([3,5,1,8,3,5,2,2])

a running window of size 2 and skip lengths of 2 should result in: [2, 7, 2, 0] since the first window is 3, 5, the second window is 1,8 etc.

Surely it can be done using a simple for-loop, but I'm struggling with thinking of better solutions.

Any help would be appreciated.

2
  • What do you mean by distance between the maximum and minimum values for this window? What is length of each "skip" of the window? You didn't list the final expected output for the given sample. Commented Aug 12, 2018 at 12:01
  • Hey @Divakar, I actually did. a running window of size 2 and skip lengths of 2 should result in: [2, 7, 2, 0] since the first window is 3, 5, the second window is 1,8 etc. Commented Aug 12, 2018 at 13:07

2 Answers 2

2

Adopting a bit from this answer, what you can do is

from numpy.lib.stride_tricks import as_strided

def running_max_min(a, window_size, step_size):
    nrows = (a.size - window_size)//step_size + 1
    n = a.strides[0]
    s = as_strided(a, shape=(nrows, window_size), strides=(step_size*n, n))
    return s.ptp(1)

For instance,

In [22]: running_max_min(x_array, 2, 2)
Out[22]: array([2, 7, 2, 0])
Sign up to request clarification or add additional context in comments.

2 Comments

Works perfectly. Thank you!
for more information, the discussion on the Suggestion: Sliding Window Function on Numpy's Github is quite interesting
2

Here is a solution using the maximum and minimum filters from ndimage:

import numpy as np

from scipy.ndimage import maximum_filter
from scipy.ndimage import minimum_filter

def max_minus_min(a, length, step=1):
    a = np.asarray(a)
    center = length//2 # shift the window to the right
    len_output = len(a)-length+1 # crop the output to keep only full windows
    max_a = maximum_filter(a, size=length, origin=-center, mode='nearest')[:len_output:step]
    min_a = minimum_filter(a, size=length, origin=-center, mode='nearest')[:len_output:step]
    return max_a - min_a

print(max_minus_min([3,5,1,8,3,5,2,2], 2, 2))  # array([2, 7, 2, 0])
print(max_minus_min([3,5,1,8,3,5,2,2], 2, 1))  # array([2, 4, 7, 5, 2, 3, 0])
print(max_minus_min([0, 0, 0, 0, 1, 0, 0, 0], 4, 1))  # array([0, 1, 1, 1, 1])
print(max_minus_min([0, 0, 0, 0, 1, 0, 0, 0], 4, 3))  # array([0, 1])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.