dataframe logical_and 适用于等于,不适用于不等于

dataframe logical_and works fine with equals and don't work with not equals

请帮助我理解为什么“不等于”条件无法正常工作。

>>>d = {'a' : [1, 2, 3, 3, 1, 4],
>>>     'b' : [4, 3, 2, 1, 2, 2]}
>>>df = pd.DataFrame(d)
    a   b
0   1   4
1   2   3
2   3   2
3   3   1
4   1   2
5   4   2

如果我使用 logical_and:

的相等条件,我们会得到正确的结果
>>>df[np.logical_and(df['a']==3, df['b']==2)]
    a   b
2   3   2

但是,如果我们将条件更改为不等于,它就会停止正常工作:

>>>df[np.logical_and(df['a']!=3, df['b']!=2)]
    a   b
0   1   4
1   2   3

这类似于条件 OR 而不是 AND。

但是如果我们在 np.logical_and

之前使用 ~ 它又可以正常工作了
>>>df[~np.logical_and(df['a']==3, df['b']==2)]
    a   b
0   1   4
1   2   3
3   3   1
4   1   2
5   4   2

我应该了解哪些逻辑条件以避免失败?

我想你应该明白了De Morgan's Laws:

not (A or B) == (not A) <b>and</b> (not B)
not (A and B) == (not A) <b>or</b> (not B)

这只是propositional logic,与Python本身无关

我们可以自己验证一个道理table。如果我们对 A and B 求真 table,我们会看到:

 |A|a|
-+-+-+
B|T|F|
-+-+-+
b|F|F|
-+-+-+

这里A表示A为真,a表示A为假(B同理)。我们将 T 表示为真,将 F 表示为假。现在相反的 table 是这样的:

 |A|a|
-+-+-+
B|F|T|
-+-+-+
b|T|T|
-+-+-+

但是如果我们为 (not A) and (not B) 构造一个真值 table 我们得到:

 |A|a|
-+-+-+
B|F|F|
-+-+-+
b|F|T|
-+-+-+

所以两者等价。

这样看:如果条件是:

A must be 5 and B must be 3.

那么反过来就是不是 A一定不能是5,B一定不能是3。因为现在 A 为 5 且 B 为 2 的情况不满足我们的第一个条件,但它也不满足我们的(错误的)第二个要求。相反的是:

A must not be 5 or B must not be 3 (opposite)

因为两者之一不是 5 或 3 就足够了。

如果您正在尝试过滤数据帧,您可能想尝试不同的方法。看看dataframe.loc

所以在你的例子中试试:

df.loc[(df['a'] != 3) & (df['b'] != 2)]

它让事情更易读,imo

另一种 Pandas 方法:

df.query("a != 3 or b != 4")