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")
请帮助我理解为什么“不等于”条件无法正常工作。
>>>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")