Numpy - 根据索引将2D数组拆分为子数组

时间:2022-02-27 12:17:32

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.argwhere可以很容易地找到这些位置,并且np.split似乎很自然。我想要的输出是

>>> 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.

np.split和相应的组件vsplit,hsplit和dsplit只能在指定的轴和索引数组中工作。

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.

在我的情况下,我试图只从几个样本近似图像。因此,我希望以最明显和最直观的方式分割图像。我希望图像基本上分成象限。例如,此图像的右下角将属于36个术语而不是22个术语。

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

有没有一种简单的方法可以做到这一点,还是我必须自己解析它?

1 个解决方案

#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.

这将为此数据集生成所需的拆分;但它取决于对数据布局的几个假设,这些假设是您所指定的,而且可能不成立。但是人们可以修改一般的想法以适应各种情况。

#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.

这将为此数据集生成所需的拆分;但它取决于对数据布局的几个假设,这些假设是您所指定的,而且可能不成立。但是人们可以修改一般的想法以适应各种情况。