2017-10-16 148 views
1

我試圖刪除第i行和第i列,當行i 第i列包含全0時。例如,在這種情況下,我們可以看到第0行全爲零,第0列全爲零,因此行和第0列被刪除。與行列對2和4相同。行1全是0,但列1不是這樣都不會被刪除。使用numpy高效地測試矩陣行和列

[0,0,0,0,0] 
[0,1,0,1,0] 
[0,0,0,0,0] 
[0,0,0,0,0] 
[0,0,0,0,0] 

將成爲

[1,1] 
[0,0] 

又如:

[0,0,1,0,0,1] 
[0,0,0,0,0,0] 
[0,0,0,0,0,0] 
[0,0,0,0,0,0] 
[0,0,0,0,0,0] 
[0,0,1,0,1,0] 

將變爲:

[0,1,0,1] 
[0,0,0,0] 
[0,0,0,0] 
[0,1,1,0] 

這是我使用的計算代碼:

def remove(matrix): 
    for i, x in reversed(list(enumerate(matrix))): 
     if np.all(matrix == 0, axis=0)[i] and np.all(matrix == 0, axis=1)[i]: 
      matrix = np.delete(matrix,i,axis=0) 
      matrix = np.delete(matrix,i,axis=1) 
    return matrix 

測試此線後,迄今爲止最耗時:

if np.all(matrix == 0, axis=0)[i] and np.all(matrix == 0, axis=1)[i]: 

是否有檢驗這樣一個行和列一個更合適的方法?我使用的矩陣是一個稀疏二元矩陣。我沒有使用任何稀疏矩陣類只是ndarray。

+0

不 - 我也這麼認爲在第一,但我相信原來的問題要同時去除行和列時都爲零。 –

+0

以OP的例子來判斷,我相信是這樣的。當然,十字的行列索引必須匹配。 –

+0

是的,這是我的意思是抱歉的混淆。 –

回答

2

與蒙矢量化的方法 -

def remove_vectorized(a): 
    mask = a==0 
    m_row = ~mask.all(1) 
    m_col = ~mask.all(0) 
    comb_mask = m_row | m_col 
    return a[comb_mask][:,comb_mask] #or a[np.ix_(comb_mask, comb_mask)] 

樣品試驗

案例#1:

In [485]: a 
Out[485]: 
array([[0, 0, 0, 0, 0], 
     [0, 1, 0, 1, 0], 
     [0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0]]) 

In [486]: remove_vectorized(a) 
Out[486]: 
array([[1, 1], 
     [0, 0]]) 

案例#2:

In [489]: a 
Out[489]: 
array([[0, 0, 1, 0, 0, 1], 
     [0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0], 
     [0, 0, 1, 0, 1, 0]]) 

In [490]: remove_vectorized(a) 
Out[490]: 
array([[0, 1, 0, 1], 
     [0, 0, 0, 0], 
     [0, 0, 0, 0], 
     [0, 1, 1, 0]]) 
+0

我不相信這會回答原來的問題。這將刪除所有行或列都是零的列,但是 - 我認爲發佈者想要的是刪除*和*列,它們*都是0。在np.ix_()中使用它們之前,你可以通過和彼此之間的位掩碼來修復你的位置。 –

0

你可以做的一件事 - 在for循環之外評估布爾矩陣「matrix == 0」,並使用該矩陣,而不是每次運行重新評估它。

它會是這樣的:

def remove(matrix): 
    binary_matrix = matrix == 0 
    for i, x in reversed(list(enumerate(matrix))): 
     if np.all(binary_matrix , axis=0)[i] and np.all(binary_matrix , axis=1)[i]: 
      matrix = np.delete(matrix,i,axis=0) 
      matrix = np.delete(matrix,i,axis=1) 
      binary_matrix = np.delete(binary_matrix ,i,axis=0) 
      binary_matrix = np.delete(binary_matrix ,i,axis=1) 
    return matrix