使用numpy查找矩阵中所有元素均为零的行

34

我有一个大的numpy矩阵M。矩阵的某些行所有元素都是零,我需要得到这些行的索引。我正在考虑的朴素方法是循环遍历矩阵中的每一行,然后检查每个元素。

使用numpy,有什么更好更快的方法来实现这个目标?

4个回答

65

以下是一种方法。假设已使用import numpy as np导入了numpy。

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

In [21]: np.where(~a.any(axis=1))[0]
Out[21]: array([2, 4])

这是对这个答案的轻微变化:如何检查矩阵是否包含零列?

下面是具体操作:

any方法会在数组中任一值为“真值”时返回True。非零数字被认为是True,而0被认为是False。通过使用参数axis=1,该方法应用于每一行。对于示例a,我们有:

In [32]: a.any(axis=1)
Out[32]: array([ True,  True, False,  True, False], dtype=bool)

因此,每个值表示对应行是否包含非零值。 ~ 运算符是二进制的“not”或补码:

In [33]: ~a.any(axis=1)
Out[33]: array([False, False,  True, False,  True], dtype=bool)

一个给出相同结果的替代表达式是(a == 0).all(axis=1)

使用where函数来获取行索引,它会返回其参数为True的索引:

In [34]: np.where(~a.any(axis=1))
Out[34]: (array([2, 4]),)

请注意,where返回一个包含单个数组的元组。 where适用于n维数组,因此它始终返回一个元组。 我们需要在该元组中获取单个数组。

In [35]: np.where(~a.any(axis=1))[0]
Out[35]: array([2, 4])

2

如果元素是int(0),则接受的答案有效。如果您想查找所有值都为0.0(浮点数)的行,则必须使用np.isclose()

print(x)
# output
tensor([[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., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
         0., 1., 0.],
        [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 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.],
])
np.where(np.all(np.isclose(labels, 0), axis=1))
(array([ 0, 3]),)

注意:这也适用于PyTorch张量,这对于当您想要查找零多热编码向量时非常有用。

1

使用np.sum的解决方案,
如果您想使用阈值,则非常有用。

a = np.array([[1.0, 1.0, 2.99],
          [0.0000054, 0.00000078, 0.00000232],
          [0, 0, 0],
          [1, 1, 0.0],
          [0.0, 0.0, 0.0]])
print(np.where(np.sum(np.abs(a), axis=1)==0)[0])
>>[2 4]
print(np.where(np.sum(np.abs(a), axis=1)<0.0001)[0])
>>[1 2 4]  

使用np.prod检查行是否至少包含一个零元素

print(np.where(np.prod(a, axis=1)==0)[0])
>>[2 3 4]

0
a =  numpy.array([[10,0],[0,0],[0,10]])
isZero = numpy.all(a == 0, axis=1)
deleteFullZero = a[~numpy.all(a== 0, axis=1)] 
#isZero >> [False True False]
#deleteFullZero >> [[10 0][0,10]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接