问题描述
在纯 Python 中,None or True
返回 True
。
但是,当我在包含 None 值的两个系列之间执行 |
时,使用熊猫时,结果与我预期的不一样:
>>> df.to_dict()
{'buyBox': {0: None},'buyBox_y': {0: True}}
>>> df
buyBox buyBox_y
0 None True
>>> df['buyBox'] = (df['buyBox'] | df['buyBox_y'])
>>> df
buyBox buyBox_y
0 False True
预期结果:
>>> df
buyBox buyBox_y
0 True True
我通过两次应用 OR 操作得到了我想要的结果,但我不明白为什么要这样做。
我不是在寻找解决方法(我通过连续应用 df['buyBox'] = (df['buyBox'] | df['buyBox_y'])
获得它)而是一个解释,即标题中的“为什么”。
解决方法
Pandas |
运算符不依赖 Python or expression
,并且行为不同。
如果两个操作数都是布尔值,则结果是数学定义的,对于 Python 和 Pandas 也是如此。
但在您的案例系列中,“buybox”的类型为 object
,而“buybox_y”的类型为 bool
。在这种情况下,Pandas |
运算符是 not commutative:
- 右操作数被强制为布尔值
- 然后尝试
bitwise or
-
None | True
是无效操作,导致None
-
- 并且结果被强制为布尔值
因此,
>>> df['buybox'] | df['buybox_y']
0 False
>>> df['buybox_y'] | df['buybox']
0 True
对于可预测的结果,您可以在尝试布尔运算之前清理数据,并使用 Pandas astype
转换为布尔类型。
对于布尔对象(即Py_True和Py_False),代码会进入快速处理分支;对于其他对象,PyObject_IsTrue() 将用于计算 int 类型的值。
在计算过程中,PyObject_IsTrue()函数会依次获取nb_bool、mp_length、sq_length的值,应该对应两个魔术方法的返回值bool() 和 len().