Pandas布尔索引中~(==)与(!=).all()的结果差异疑问
Pandas布尔索引:
~(df[names] == 0.0).all(axis=1)与(df[names] != 0.0).all(axis=1)的差异解析 问题背景
有如下4列的DataFrame:
dic = { "a": [1,1,1,0,0,1,1], "b": [0,0,1,1,0,0,0], "c": [1,0,1,0,0,1,0], "d": [0,0,1,0,0,1,0], } df = pd.DataFrame(data=dic)
输出结果:
a b c d 0 1 0 1 0 1 1 0 0 0 2 1 1 1 1 3 0 1 0 0 4 0 0 0 0 5 1 0 1 1 6 1 0 0 0
需求是筛选出b、c、d列不全为0的行(忽略a列)。
使用~(df[names] == 0.0).all(axis=1)得到预期结果:
names = ["b","c","d"] df_A = df.loc[~(df[names] == 0.0).all(axis=1)]
输出:
a b c d 0 1 0 1 0 2 1 1 1 1 3 0 1 0 0 5 1 0 1 1
但使用(df[names] != 0.0).all(axis=1)得到完全不同的结果:
names = ["b","c","d"] df_B = df.loc[(df[names] != 0.0).all(axis=1)]
输出:
a b c d 2 1 1 1 1
差异原因
这两种写法逻辑完全不等价,核心是对“不全为0”的理解和布尔运算的逻辑顺序:
(df[names] == 0.0).all(axis=1):判断每行的b、c、d列全部等于0,返回布尔序列,其中True表示该行三列全为0。加上取反~后,~(...)表示**“并非全部为0”**,也就是“至少有一列不为0”,正好匹配需求——筛选出不全为0的行。(df[names] != 0.0).all(axis=1):判断每行的b、c、d列全部不等于0,返回布尔序列,只有当该行三列都不为0时才返回True。这对应的是“全不为0”的筛选条件,和“不全为0”是完全不同的逻辑。
简单总结:
~(全为0)= 至少有一个不为0(即不全为0)全不为0= 所有列都不为0
前者包含“部分为0、部分不为0”和“全不为0”的行,后者只包含“全不为0”的行,因此结果差异明显。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

