使用numpy有效地测试矩阵行和列

时间:2017-10-16 16:13:39

标签: python performance numpy matrix sparse-matrix

当i 列i包含全0时,我试图删除第i行和第i列。例如,在这种情况下,我们可以看到第0行全部为零,第0列全部为零,因此删除了行0和第0列。与行列对2和4相同。行1全为零,但列1不是,因此都不会被删除。

[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的任何稀疏矩阵类。

2 个答案:

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

答案 1 :(得分:0)

你可以做的一件事 - 评估布尔矩阵"矩阵== 0"在for循环之外,并使用该矩阵而不是每次运行时重新评估它。

它类似于:

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