2013-09-01 10 views
5

Dokładniej, mam listę wierszy/kolumn, które należy zignorować przy wyborze maksymalnego wpisu. Innymi słowy, przy wyborze maksymalnego górnego trójkąta, niektóre wskaźniki muszą zostać pominięte. W takim przypadku, jaki jest najskuteczniejszy sposób na znalezienie położenia górnego trójkąta?Skuteczny sposób na znalezienie indeksu maksymalnej górnej pozycji trójkątnej w tablicy numpy?

Na przykład:

>>> a 
array([[0, 1, 1, 1], 
     [1, 2, 3, 4], 
     [4, 5, 6, 6], 
     [4, 5, 6, 7]]) 
>>> indices_to_skip = [0,1,2] 

Muszę znaleźć indeks min elementu spośród wszystkich elementów w górnym trójkącie z wyjątkiem wpisów a[0,1], a[0,2] i a[1,2].

+0

Czy otrzymując przykład? – nneonneo

+0

Właśnie edytowałem pytanie. Dzięki! – methane

+0

Więc, w tym przykładzie, bierzesz maksymalnie [1,4,6]? Czy zawierasz przekątną, czy nie? – nneonneo

Odpowiedz

5

Można użyć np.triu_indices_from:

>>> np.vstack(np.triu_indices_from(a,k=1)).T 
array([[0, 1], 
     [0, 2], 
     [0, 3], 
     [1, 2], 
     [1, 3], 
     [2, 3]]) 

>>> inds=inds[inds[:,1]>2] #Or whatever columns you want to start from. 
>>> inds 
array([[0, 3], 
     [1, 3], 
     [2, 3]]) 


>>> a[inds[:,0],inds[:,1]] 
array([1, 4, 6]) 

>>> max_index = np.argmax(a[inds[:,0],inds[:,1]]) 
>>> inds[max_index] 
array([2, 3]]) 

czyli

>>> inds=np.triu_indices_from(a,k=1) 
>>> mask = (inds[1]>2) #Again change 2 for whatever columns you want to start at. 
>>> a[inds][mask] 
array([1, 4, 6]) 

>>> max_index = np.argmax(a[inds][mask]) 
>>> inds[mask][max_index] 
array([2, 3]]) 

Do powyższego można użyć inds[0] pominąć certains wiersze.

Aby pominąć konkretne wiersze lub kolumny:

def ignore_upper(arr, k=0, skip_rows=None, skip_cols=None): 
    rows, cols = np.triu_indices_from(arr, k=k) 

    if skip_rows != None: 
     row_mask = ~np.in1d(rows, skip_rows) 
     rows = rows[row_mask] 
     cols = cols[row_mask] 

    if skip_cols != None: 
     col_mask = ~np.in1d(cols, skip_cols) 
     rows = rows[col_mask] 
     cols = cols[col_mask] 

    inds=np.ravel_multi_index((rows,cols),arr.shape) 
    return np.take(arr,inds) 

print ignore_upper(a, skip_rows=1, skip_cols=2) #Will also take numpy arrays for skipping. 
[0 1 1 6 7] 

Obie mogą być łączone i twórcze wykorzystanie logicznego indeksowania może pomóc przyspieszyć konkretne przypadki.

Coś ciekawego że natknąłem, szybszy sposób, aby wziąć górne indeksy triu:

def fast_triu_indices(dim,k=0): 

    tmp_range = np.arange(dim-k) 
    rows = np.repeat(tmp_range,(tmp_range+1)[::-1]) 

    cols = np.ones(rows.shape[0],dtype=np.int) 
    inds = np.cumsum(tmp_range[1:][::-1]+1) 

    np.put(cols,inds,np.arange(dim*-1+2+k,1)) 
    cols[0] = k 
    np.cumsum(cols,out=cols) 
    return (rows,cols) 

jej o ~ 6x szybciej mimo to nie działa dla k<0:

dim=5000 
a=np.random.rand(dim,dim) 

k=50 
t=time.time() 
rows,cols=np.triu_indices(dim,k=k) 
print time.time()-t 
0.913508892059 

t=time.time() 
rows2,cols2,=fast_triu_indices(dim,k=k) 
print time.time()-t 
0.16515994072 

print np.allclose(rows,rows2) 
True 

print np.allclose(cols,cols2) 
True 
+0

To wygląda dobrze, ale co ze znajdowaniem indeksu elementu max, a nie tylko samego elementu max? – methane

+0

@methane I zaktualizowałem dwa pierwsze przykłady. Powinieneś być w stanie zabrać go stamtąd. – Daniel

Powiązane problemy