1

I'm looking to do some basic clustering on a boolean numpy array and I'm basically just trying to do 2d averaging with a mask, but I feel like there must be a better solution than what I've got, since it's slow and inelegant:

def grab_window(location, array, window=(3,3)):
    minimums = [min(0, i-a) for i, a in zip(location, window)]
    maximums = [(i + a) for i, a in zip(location, window)]
    answer = array
    for i, _ in enumerate(location):
        answer = answer[slice(minimums[i],maximums[i])]
    return answer

And then I basically just iterate through the original array, multiplying each window by a kernel, and returning the mean of the modified window.

It seems like there must be a filter or something similar that would have the same effect, but I haven't been able to find one thus far.

edit: location is a tuple of a form similar to window.

For instance, if we were to do the simplest version of this, with a uniform 1-ply mask I would be looking for something along these lines:

import numpy as np
test = np.arange(0,24).reshape(6, 4)
footprint = [
[1,1,1],
[1,0,1],
[1,1,1]
]
some_function(test, footprint)
array([[ 1,  2,  3,  4],
   [ 4,  5,  6,  6],
   [ 8,  9, 10, 10],
   [12, 13, 14, 14],
   [16, 17, 18, 18],
   [18, 19, 20, 21]])
5
  • give us the sample of location. Commented Apr 13, 2014 at 23:42
  • 1
    sorry, array please. Commented Apr 13, 2014 at 23:57
  • are the tuples location and window always pairs? Commented Apr 14, 2014 at 0:11
  • For future Googlers and for people trying to answer, could you give samples of the input data as Python code and make this a complete example? Commented Apr 14, 2014 at 13:39
  • @MrE While I don't think it was relevant for people trying to answer, as the only input data I didn't provide was an arbitrary array, for the sake for Googlers I've added some more dialog to both my question and answer. Commented Apr 14, 2014 at 17:22

1 Answer 1

1

Turns out scipy totally has a function that already does this. generic_filter actually does exactly this in a much more stable way as mentioned in How to apply ndimage.generic_filter()

Example:

def some_avg(values):
    return values.mean()

footprint = np.array([
    [1,1,1],
    [1,0,1],
    [1,1,1]
])

test = test = np.arange(0,24).reshape(6, 4)

scipy.ndimage.filters.generic_filter(test, some_avg, footprint=footprint)

array([[ 1,  2,  3,  4],
   [ 4,  5,  6,  6],
   [ 8,  9, 10, 10],
   [12, 13, 14, 14],
   [16, 17, 18, 18],
   [18, 19, 20, 21]])
Sign up to request clarification or add additional context in comments.

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.