基于关节条件的pandas切片行

时间:2017-03-01 21:51:48

标签: python pandas numpy

考虑以下数据框-df

    one  two  three  four  five  six  seven  eight
0   0.1  1.1    2.2   3.3   3.6  4.1    0.0    0.0
1   0.1  2.1    2.3   3.2   3.7  4.3    0.0    0.0
2   1.6  0.0    0.0   0.0   0.0  0.0    0.0    0.0
3   0.1  1.2    2.5   3.7   4.4  0.0    0.0    0.0
4   1.7  2.1    0.0   0.0   0.0  0.0    0.0    0.0
5   2.1  3.2    0.0   0.0   0.0  0.0    0.0    0.0
6   2.1  2.3    3.2   4.3   0.0  0.0    0.0    0.0
7   2.2  0.0    0.0   0.0   0.0  0.0    0.0    0.0
8   0.1  1.8    0.0   0.0   0.0  0.0    0.0    0.0
9   1.6  0.0    0.0   0.0   0.0  0.0    0.0    0.0

我想选择任何列值为'3.2'的所有行,但同时所选行的值不应为'0.1'或'1.2'

我可以使用以下查询获得第一部分

df[df.values == 3.2]

但不能将其与查询的第二部分(关节!=条件)

结合起来

我也收到以下错误

  

DeprecationWarning:elementwise!=比较失败;这将在未来引发错误。

在尝试以下

时,在较大的数据集上(但不在较小的副本上)

df[df.values != [0.1,1.2]]

//编辑:

@pensen,这里是输出,行1,15,27,35的值为'0.1',但根据它们应该被过滤的条件。

contains = df.eq(3.2).any(axis=1)
not_contains = ~df.isin([0.1,1.2]).any(axis=1)
print(df[contains & not_contains])
      0    1    2    3    4    5    6    7
1    0.1  2.1  3.2  0.0  0.0  0.0  0.0  0.0
15   0.1  1.1  2.2  3.2  3.3  3.6  3.7  0.0
27   0.1  2.1  2.3  3.2  3.6  3.7  4.3  0.0
31   3.2  0.0  0.0  0.0  0.0  0.0  0.0  0.0
35   0.1  1.7  2.1  3.2  3.6  3.7  4.3  0.0

这里是0:36行的原始数据集,用于复制上面的输出

      0    1    2    3    4    5    6    7
 0   4.1  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 1   0.1  2.1  3.2  0.0  0.0  0.0  0.0  0.0
 2   0.1  2.4  2.5  0.0  0.0  0.0  0.0  0.0
 3   2.4  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 4   4.4  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 5   1.1  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 6   0.1  2.1  4.1  0.0  0.0  0.0  0.0  0.0
 7   4.4  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 8   1.7  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 9   2.2  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 10  1.1  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 11  1.1  4.1  0.0  0.0  0.0  0.0  0.0  0.0
 12  0.1  2.2  3.3  3.6  0.0  0.0  0.0  0.0
 13  0.1  1.8  3.3  0.0  0.0  0.0  0.0  0.0
 14  0.1  1.2  1.3  2.5  3.7  4.2  0.0  0.0
 15  0.1  1.1  2.2  3.2  3.3  3.6  3.7  0.0
 16  1.3  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 17  1.3  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 18  1.3  2.5  0.0  0.0  0.0  0.0  0.0  0.0
 19  0.1  1.2  2.5  3.7  4.4  0.0  0.0  0.0
 20  1.2  4.4  0.0  0.0  0.0  0.0  0.0  0.0
 21  4.3  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 22  1.1  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 23  0.1  2.2  2.4  2.5  3.7  0.0  0.0  0.0
 24  0.1  2.4  4.3  0.0  0.0  0.0  0.0  0.0
 25  1.7  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 26  0.1  1.1  4.1  0.0  0.0  0.0  0.0  0.0
 27  0.1  2.1  2.3  3.2  3.6  3.7  4.3  0.0
 28  1.4  2.2  3.6  4.1  0.0  0.0  0.0  0.0
 29  1.8  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 30  1.2  4.4  0.0  0.0  0.0  0.0  0.0  0.0
 31  3.2  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 32  3.6  4.1  0.0  0.0  0.0  0.0  0.0  0.0
 33  2.1  2.4  0.0  0.0  0.0  0.0  0.0  0.0
 34  0.1  1.8  0.0  0.0  0.0  0.0  0.0  0.0
 35  0.1  1.7  2.1  3.2  3.6  3.7  4.3  0.0

这是实际数据集的link

3 个答案:

答案 0 :(得分:4)

您可以简单地执行以下操作:

df.eq(3.2).any(axis=1) & ~df.isin([0.1, 1.2]).any(axis=1)

或者更明确地说:

contains = df.eq(3.2).any(axis=1)
not_contains = ~df.isin([0.1,1.2]).any(axis=1)

print(df[contains & not_contains])
   one    two    three    four    five    six    seven    eight
5  2.1    3.2    0.0      0.0     0.0     0.0    0.0      0.0
6  2.1    2.3    3.2      4.3     0.0     0.0    0.0      0.0

答案 1 :(得分:3)

对于性能,特别是因为你提到了大型数据集,如果你想要只排除两个数字,这里有一种方法是数组数据 -

a = df.values
df_out = df.iloc[(a == 3.2).any(1) & (((a!=0.1) & (a!=1.2)).all(1))]

示例运行 -

In [43]: a = df.values

In [44]: df.iloc[(a == 3.2).any(1) & (((a!=0.1) & (a!=1.2)).all(1))]
Out[44]: 
   one  two  three  four  five  six  seven  eight
5  2.1  3.2    0.0   0.0     0    0      0      0
6  2.1  2.3    3.2   4.3     0    0      0      0

答案 2 :(得分:1)

你可以结合条件。

>>> df[(df == 3.2).any(1) & ~df.isin([0.1, 1.2]).any(1)]

   one  two  three  four  five  six   seven  eight
5  2.1  3.2    0.0   0.0   0.0   0.0    0.0    0.0
6  2.1  2.3    3.2   4.3   0.0   0.0    0.0    0.0