Numpy选择非零行

时间:2015-06-28 07:03:08

标签: python numpy

我想只选择没有任何0元素的行。

data = np.array([[1,2,3,4,5],
                [6,7,0,9,10],
                [11,12,13,14,15],
                [16,17,18,19,0]])

结果将是:

array([[1,2,3,4,5],
       [11,12,13,14,15]])

2 个答案:

答案 0 :(得分:9)

使用numpy.all

>>> data[np.all(data, axis=1)]
array([[ 1,  2,  3,  4,  5],
       [11, 12, 13, 14, 15]])

答案 1 :(得分:3)

您可以使用data ==0检测所有零,这将为您提供一个布尔数组,然后沿其上的每一行执行np.any。或者,您可以使用data!=0检测所有非零,然后执行np.all以获取没有任何零的行的行掩码。

我也可以使用np.einsum替换np.any,我个人认为这是一种疯狂,但是以一种好的方式,因为它会给我们带来明显的性能提升,因为我们稍后会在此解决方案中确认。

因此,您将有下面列出的三种方法。

方法#1:

rows_without_zeros = data[~np.any(data==0, axis=1)]

方法#2:

rows_without_zeros = data[np.all(data!=0, axis=1)]

方法#3:

rows_without_zeros = data[~np.einsum('ij->i',data ==0)]

运行时测试 -

本节对此解决方案中提出的三种解决方案进行计时,并且还包括基于np.all方法的@Ashwini Chaudhary's approach时序,但不使用掩码或布尔数组(至少在前端中不是这样)

In [129]: data = np.random.randint(-10,10,(10000,10))

In [130]: %timeit data[np.all(data, axis=1)]
1000 loops, best of 3: 1.09 ms per loop

In [131]: %timeit data[np.all(data!=0, axis=1)]
1000 loops, best of 3: 1.03 ms per loop

In [132]: %timeit data[~np.any(data==0,1)]
1000 loops, best of 3: 1 ms per loop

In [133]: %timeit data[~np.einsum('ij->i',data ==0)]
1000 loops, best of 3: 825 µs per loop

因此,似乎向np.allnp.any提供掩码会比基于非掩码的方法提供一点(大约 9% )性能提升。使用einsum,您正在查看基于20%np.any方法的 np.all 改进,这还不错!