在Python中提取多个子矩阵

alv*_*zcl 10 python indexing

如果我的稀疏矩阵有多个非零值区域,我试图提取多个子矩阵.

例如,假设我有以下矩阵:

x = np.array([0,0,0,0,0,0],
             [0,1,1,0,0,0],
             [0,1,1,0,0,1],
             [0,0,0,0,1,1],
             [0,0,0,0,1,0])
Run Code Online (Sandbox Code Playgroud)

然后我需要能够提取具有非零值的区域,即

x_1 = [[1,1]
       [1,1]]
Run Code Online (Sandbox Code Playgroud)

x_2 = [[0,1],
       [1,1],
       [1,0]]
Run Code Online (Sandbox Code Playgroud)

我一直在使用np.where()来查找非零值的索引并仅返回一个子矩阵的区域,但是如何将其扩展到稀疏矩阵中的所有可能的子区域?

谢谢!

Irs*_*hat 7

程序:

  1. 使用全零删除前导和尾随行和列.(不是中间的)
  2. 查找所有空行和列,并在这些索引上拆分矩阵.这将创建一个矩阵列表
  3. 对于每个新创建的矩阵,递归地重复该过程,直到不可能进一步分割为止

码:

def delrc(arr):
    while True:     # delete leading rows with all zeros
    if np.all(arr[0]==0):
        arr=np.delete(arr,0,axis=0)
    else: break
    while True:     # delete trailing rows with all zeros
    if np.all(arr[-1]==0):
        arr=np.delete(arr,-1,axis=0)
    else: break
    while True:     # delete leading cols with all zeros
    if np.all(arr[:,0]==0):
        arr=np.delete(arr,0,axis=1)
    else: break
    while True:     # delete trailing cols with all zeros
    if np.all(arr[:,-1]==0):
        arr=np.delete(arr,-1,axis=1)
    else: break
    return arr

def rcsplit(arr):
    if np.all(arr==0): return []    # if all zeros return
    global  res
    arr = delrc(arr)        # delete leading/trailing rows/cols with all zeros
    print arr
    indr = np.where(np.all(arr==0,axis=1))[0]
    indc = np.where(np.all(arr==0,axis=0))[0]
    if not indr and not indc:   # If no further split possible return
    res.append(arr)
    return
    arr=np.delete(arr,indr,axis=0)  #delete empty rows in between non empty rows
    arr=np.delete(arr,indc,axis=1)  #delete empty cols in between non empty cols
    arr=np.split(arr,indc,axis=1)   # split on empty (all zeros) cols 
    print arr
    arr2=[]
    for i in arr:
    z=delrc(i)  
    arr2.extend(np.split(z,indr,axis=0))   # split on empty (all zeros) rows
    for i in arr2:
    rcsplit(np.array(i))        # recursive split again no further splitting is possible

if __name__=="__main__":

    import numpy as np 
    res = []   
    arr = np.array([[0,0,0,0,0,0],
        [0,1,1,0,0,0],
        [0,1,1,0,0,1],
        [0,0,0,0,1,1],
        [0,0,0,0,1,0]])
    rcsplit(arr)
    for i in res: print i
Run Code Online (Sandbox Code Playgroud)