5

I have an array that I'd like to split into sub-arrays based on the obvious and non-overlapping rectangles:

>>> A = array([[  0.,  nan,   2.,  nan,   4.,  nan,    6,  nan],
               [ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan],
               [ nan,  nan,  nan,  nan,   20,  nan,   22,  nan],
               [ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan],
               [ 32.,  nan,  34.,  nan,  36.,  nan,  nan,  nan],
               [ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan],
               [ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan],
               [ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan]])

These locations are easily findable with np.argwhere, and it seems natural to do it the np.split. My desired output is

>>> np.split_2d(A)
    (array([[  0.,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]])
     array([[  2.,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]])
     array([[ 32.,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]])
     array([[ 34.,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]
            [ nan,  nan ]])
     array([[ 4.,  nan ]
            [ nan,  nan ]])
     array([[ 6.,  nan ]
            [ nan,  nan ]])
     array([[ 20,  nan ]
            [ nan,  nan ]])
     array([[ 22,  nan ]
            [ nan,  nan ]])
     array([[ 36.,  nan,  nan,  nan ]
            [ nan,  nan,  nan,  nan ]
            [ nan,  nan,  nan,  nan ]
            [ nan,  nan,  nan,  nan ]]))
     ...

np.split and the corresponding components vsplit, hsplit and dsplit and only work along a specified axis and an array of indices.

A question on binning answers a similar question, but in my case the bins are not regularly spaced and not the same size.

In my case, I'm trying to approximate an image from only a few samples. Hence, I want the image to be split up in the most obvious and intuitive way. I want the image to be divided up into quadrants essentially. For example, the lower right corner of this image would belong to the 36 term and not the 22 term.

Is there an easy way to do this, or do I have to parse it all myself?

4
  • Hi Scott, will you please add an example of your desired output? Commented Dec 27, 2013 at 4:33
  • It was included, but I made it more clear and fixed it up a bit. Commented Dec 27, 2013 at 20:33
  • The rectangles are not all that obvious, since this kind of tiling isn't unique. The bottom right could belong to either 22 or 36. There appears to be an implied hierarchy to the problem though. Would a recursive splitting in two along rows/columns, conditional on the non-nanness of the newly created corners achieve your goal? Commented Dec 29, 2013 at 22:22
  • Right. I should clarify. This array is the output of the wavelet transform, meaning that it should be split up into more square shapes. 36 belongs to a more coarse term and 4,6,20 and 22 belong to a finer term. I added more detail to the question. Commented Dec 30, 2013 at 1:12

1 Answer 1

2
def recurse(A):
    if A.shape[0]>A.shape[1]:   #split longest axis first
        if not np.isnan( A[0,A.shape[1]//2]):
            return [rect for part in np.split(A, 2, axis=1) for rect in recurse(part)]
        if not np.isnan( A[A.shape[0]//2,0]):
            return [rect for part in np.split(A, 2, axis=0) for rect in recurse(part)]
    else:
        if not np.isnan( A[A.shape[0]//2,0]):
            return [rect for part in np.split(A, 2, axis=0) for rect in recurse(part)]
        if not np.isnan( A[0,A.shape[1]//2]):
            return [rect for part in np.split(A, 2, axis=1) for rect in recurse(part)]
    return [A]

This produces the desired split for this dataset; but it hinges on several assumptions about the layout of the data, which you havnt specified, and which may not hold. But one could modify the general idea to accommodate a variety of circumstances.

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.