2014-11-03 1 views
10

Sto tentando di estrarre più submatrices se la mia matrice sparse ha più regioni di valori diversi da zero.Estrazione di più submatrices in Python

Ad esempio, Say Ho la seguente matrice:

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]) 

Allora devo essere in grado di estrarre le regioni con valori diversi da zero, cioè

x_1 = [[1,1] 
     [1,1]] 

e

x_2 = [[0,1], 
     [1,1], 
     [1,0]] 

Sto usando np.where() per trovare gli indici di valori diversi da zero e returni ng la regione per un solo submatrix, ma come posso estenderlo a tutte le possibili sottoregioni nella mia matrice sparsa?

Grazie!

risposta

7

Procedura:

  1. Elimina iniziali e finali righe e colonne con tutti zeri. (Non di mezzo)
  2. Trova tutte le righe e le colonne vuote e matrice divisa su questi indici. Questo crea un elenco di matrici
  3. Per ogni ripetizione di matrice appena creato la procedura in modo ricorsivo fino a quando non ulteriormente la scissione è possibile

Codice:

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 
+0

grazie ma sto ottenendo un errore con la definizione globale: NameError: 'res' nome globale non è definita – alvarezcl

+0

Inoltre non sembra funzionare per il caso generale di qualsiasi due sottomatrici. – alvarezcl

+0

@alvarezcl, È necessario prima definire 'res = []' nella funzione principale. Ho caricato il vero codice completo. Provalo. Inoltre, funziona per ogni caso di due sottomatrici. L'ho provato prima per molti casi. –

3

È possibile utilizzare built-in per questo.

from scipy.ndimage.measurements import find_objects, label 
from scipy.ndimage import generate_binary_structure as gbs 

import numpy as np 

# create array 
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]]) 

# define labeling structure to inlcude adjacent (including diagonal) cells 
struc = gbs(2,2) 

# generate array of labeled sections labels 
x2, numlabels = label(x,struc) 

# pull out first group of "ones" 
xy1 = find_objects(x2==1)[0] 

# pull out second group of "ones" 
xy2 = find_objects(x2==2)[0] 

Ora prova:

>>> x[xy1] 
    array([[1, 1], 
      [1, 1]]) 

>>> x[xy2] 
    array([[0, 1], 
      [1, 1], 
      [1, 0]]) 

Voila! Se si desidera estrarre tutte le sottosezioni, è possibile ripetere l'iterazione, il che indica quanti gruppi diversi si hanno all'interno dell'array.

+0

Questa è in realtà una soluzione migliore rispetto a quella accettata IMO. –