2014-11-03 2 views
10

Я пытаюсь извлечь несколько подматриц, если моя разреженная матрица имеет несколько областей ненулевых значений.Извлечение нескольких подматриц в Python

Например, Скажем, у меня есть следующая матрица:

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

Тогда мне нужно, чтобы иметь возможность извлечь области с ненулевыми значениями, т.е.

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

и

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

Я использую np.where(), чтобы найти индексы ненулевых значений и returni ng область только для одной подматрицы, но как я могу распространить ее на все возможные субрегионы в моей разреженной матрице?

Спасибо!

ответ

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

спасибо, но я получаю сообщение об ошибке с глобальным определением: NameError: глобальное имя «разрешение» не определен – alvarezcl

+0

Это также, кажется, не работает в общем случае любых два подматрицы. – alvarezcl

+0

@alvarezcl, вам нужно сначала определить 'res = []' в основной функции. Я загрузил фактический полный код. Попробуй. Кроме того, он работает для любого случая двух подматриц. Я тестировал его сначала для многих случаев. –

3

Вы можете использовать встроенные модули для этого.

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] 

тест:

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

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

Вуаля! Если вы хотите вытащить все подразделы, вы можете перебирать их, что говорит о том, сколько разных групп у вас в массиве.

+0

Это на самом деле лучшее решение, чем принятое IMO. –

Смежные вопросы