根据两列

时间:2016-12-30 21:33:16

标签: python arrays numpy

我有一个有四列和多行的numpy数组:

>>> dat
array([['4/5/2004', '17', 0.0, 0.0],
   ['4/5/2004', '7', 0.0, 0.0],
   ['4/5/2004', '19:48:20', 58.432488, -135.9202205],
   ['4/5/2004', '19:48:32', 58.432524300000004, 0.0],
   ['4/5/2004', '19:48:36', 58.4325365, -150.9202813]], dtype=object)  

我想删除第3列或第4列中的值等于0的所有行,结果将是:

   ([['4/5/2004', '19:48:20', 58.432488, -135.9202205],
   ['4/5/2004', '19:48:36', 58.4325365, -150.9202813]])

我可以一次一行地执行以下操作:

a = dat[~(dat[:,2]==0), :]  

返回第3列中的值不等于0的行。我可以迭代地为多列执行此操作,但在一个命令中完成所有操作会很方便。

我认为以下两个例子会起作用(但他们没有):

a = dat[~(dat[:,2]==0), :] or dat[~(dat[:,3]==0), :] 
a = dat[~(dat[:,2&3]==0), :]

希望我能找到一些简单的语法,而且在numpy帮助中无法找到。

3 个答案:

答案 0 :(得分:2)

如何使用&

>>> dat[(dat[:,2] != 0) & (dat[:,3] != 0), :]
array([['4/5/2004', '19:48:20', 58.432488, -135.9202205],
       ['4/5/2004', '19:48:36', 58.4325365, -150.9202813]], dtype=object)

产生元素"和"。

我已为!= 0更改了&,从而避免了~的其他反转。

答案 1 :(得分:2)

假设数据数组是2D,我们可以切片并查找有效数据 -

dat[~(dat[:,2:4]==0).any(1)]

或者,我们可以在np.all上使用!=0 -

dat[(dat[:,2:4]!=0).all(1)]

当感兴趣的列不是连续的列时,我们需要使用这些列ID对它们进行切片并使用相同的技术。因此,假设要检查的列ID存储在名为colID的数组或列表中,然后我们将修改这些方法,如此 -

dat[~(dat[:,colID]==0).any(1)]
dat[(dat[:,colID]!=0).all(1)]

因此,对于第3列和第4列的陈述情况,我们将:colID = [2,3]

答案 2 :(得分:2)

您明白使用or概念正确。主要区别在于您要执行逻辑或(|)或逻辑和(&)(就像您使用逻辑而非(~))。

这是有效的,因为像dat[:,3] == 0这样的操作会创建一个与dat列相同大小的数组或布尔值。当此数组用作索引时,numpy会将其解释为掩码。拆分掩码数组以突出显示这个概念:

mask = (dat[:, 2] != 0) & (dat[:, 3] != 0)
dat = dat[mask, :]

计算掩码的另一种方法如下:

mask = np.logical_and.reduce(dat[:, 2:] != 0, axis=1)

np.logical_and.reduce通过将axis=1(这是处理np.logical_and运算符的函数)应用于行来缩小列(&)上的输入数组,因此您获得一个True,其中每行的所选部分的所有元素都为True。