为什么~True不能在pandas dataframe条件下工作



我正在尝试使用开关来打开和关闭pandas数据框架中的条件。开关只是布尔变量,可以是True或False。问题是~True与False的计算结果并不像我所期望的那样相同。为什么这不起作用?

>>> dataframe = pd.DataFrame({'col1': [3, 4, 5, 6], 'col2': [6, 5, 4, 3]})
>>> dataframe
col1  col2
0     3     6
1     4     5
2     5     4
3     6     3
>>> dataframe.loc[dataframe.col1 <= dataframe.col2]
col1  col2
0     3     6
1     4     5
>>> dataframe.loc[(True) | (dataframe.col1 <= dataframe.col2)]
col1  col2
0     3     6
1     4     5
2     5     4
3     6     3
>>> dataframe.loc[(False) | (dataframe.col1 <= dataframe.col2)]
col1  col2
0     3     6
1     4     5
>>> dataframe.loc[(~True) | (dataframe.col1 <= dataframe.col2)]
col1  col2
0     3     6
1     4     5
2     5     4
3     6     3
>>> dataframe.loc[(~(True)) | (dataframe.col1 <= dataframe.col2)]
col1  col2
0     3     6
1     4     5
2     5     4
3     6     3
>>>
>>> dataframe  = pd.DataFrame({'col1': [1, 2, 3, 4], 'col2': [True, False, False, True]})
>>> dataframe
col1   col2
0     1   True
1     2  False
2     3  False
3     4   True
>>> dataframe.loc[dataframe.col2]
col1  col2
0     1  True
3     4  True
>>> dataframe.loc[not dataframe.col2]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/pandas/core/generic.py", line 1537, in __nonzero__
raise ValueError(
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> dataframe.loc[dataframe.col2 == False]
col1   col2
1     2  False
2     3  False

这是一个pandas操作符的行为(由Numpy实现)。

True不是一个pandas对象。相反,它是一个布尔值。所以很明显,~运算符不是用来反转布尔值的,只有在Pandas中才是。

如你所见:

>>> ~True
-2
>>> 

给出了-2,这是__invert__规则的魔法方法行为。

因此:

>>> bool(-2)
True
>>> 

给出True.

不要混淆Pandas和Python的行为,Pandas实现了__invert__的用法,例如:

>>> ~pd.Series([True])
0    False
dtype: bool
>>> 

可以看到,在pandas(也是Numpy)中,它反转了布尔值。因此,如果你写:

>>> dataframe.loc[~pd.Series([True]).any() | (dataframe.col1 <= dataframe.col2)]
col1  col2
0     3     6
1     4     5
>>> 

你可以清楚地看到它的行为等同于False

最好的方法是使用not:

>>> dataframe.loc[(not True) | (dataframe.col1 <= dataframe.col2)]
col1  col2
0     3     6
1     4     5
>>> 

我觉得"~"不是你想要的,也许你想用"not":

>>> dataframe.loc[(not True) | (dataframe.col1 <= dataframe.col2)]
col1  col2
0     3     6
1     4     5

最新更新