2013-09-01 16 views
5

Daha ayrıntılı olarak, maksimum girişi seçerken göz ardı edilmesi gereken bir satır/sütun listesi var. Başka bir deyişle, maksimum üst üçgen girişini seçerken, bazı endekslerin atlanması gerekir. Bu durumda, maksimum üst üçgen giriş yerini bulmak için en etkili yol nedir? ÖrneğinSayısal dizide maksimum üst üçgen girişinin dizinini bulmanın etkili yolu?

:

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

Ben girişleri a[0,1], a[0,2] ve a[1,2] hariç üst üçgeninde tüm unsurları arasında dk elemanın indeksini bulmak gerekir.

+0

Bir verebilir örnek? – nneonneo

+0

Soruyu yeni düzenledim. Teşekkürler! – methane

+0

Yani, örnekte, maksimum [1,4,6] maksimum alıyorsunuz? Diyagonal mi dahil değil misiniz? – nneonneo

cevap

5

Sen np.triu_indices_from kullanabilirsiniz:

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

Veya:

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

Yukarıdaki certains satırları atlamak için inds[0] kullanabilirsiniz için.

belirli satırları veya sütunları atlamak için:

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] 

iki kombine edilebilir ve boole endeksleme yaratıcı kullanımı belirli durumlarda hızlandırmaya yardımcı olabilir. ilginç

İçimden karşılaştım ki daha hızlı bir şekilde üst triu endekslerini almaya:

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) 

Onun ~ 6x hakkında hızlı o k<0 için çalışmıyor olsa:

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

Bu iyi görünüyor, ancak sadece maksimum elemanın kendisi değil, maksimum elemanın indeksini bulmak ne demektir? – methane

+0

@methane İlk iki örneği güncelledim. Onu oradan alabilmelisin. – Daniel

İlgili konular