pandas 两张布尔表做 OR 后全变 True,检查对齐产生的 NaN
pandas 3.1.0 的 nullable boolean 运算遇到列对齐填入的浮点 NaN,可能先转为 True。显式对齐并恢复 boolean dtype,保留缺失值语义,不要直接填 False。
两张使用 dtype="boolean" 的 DataFrame 执行 left | right,原本不确定的单元格却都变成 True。若两边列名不同、运算需要取列的并集,先检查对齐过程中产生的新列是什么 dtype。
pandas 3.1.0 存在这条具体路径:原列是可空布尔类型,缺少的一侧却可能被填成浮点 NaN。后续逻辑运算把这组浮点值按普通布尔转换处理,bool(np.nan) 为真,缺失信息便在运算前丢掉了。
对齐后把两边都恢复为可空布尔
下例中,a 与 b 是不同列,缺少的单元格代表未知,而不是默认真或默认假:
import pandas as pd
x = pd.DataFrame({"a": [True, pd.NA]}, dtype="boolean")
y = pd.DataFrame({"b": [pd.NA, True]}, dtype="boolean")
left, right = x.align(y, join="outer")
left = left.astype("boolean")
right = right.astype("boolean")
result = left | right
显式转换使新增列中的 NaN 重新成为可空布尔的缺失值。这个示例应得到 a=[True, pd.NA]、b=[pd.NA, True]。它沿用 True | 未知 = True、False | 未知 = 未知、未知 | 未知 = 未知 的三值逻辑。
这段写法限定输入表本来都表示布尔状态。若还有金额、文本或其他业务列,应只处理明确的布尔列,不能把整张混合表转成 boolean。标签重复时也应先确认应用允许的对齐关系,不要在修 dtype 时顺手删行或改标签。
填 False 会改变问题本身
fillna(False) 可能让结果看起来合理,却把未知状态变成了确定的否。例如权限、审核或告警状态中,“暂未得到数据”未必等于“不允许”或“未触发”。只有业务明确把缺失定义为假,才可使用这样的默认值。
同列、不需要对齐的运算可能表现正常,因此单独检查 x | x 不能覆盖故障条件。应比较完全不同列、部分相同列和行索引也需要对齐的情况,同时核对结果值与每列 dtype。数组层面的 AND、XOR 也不能只凭某一张表恰好得到合理结果就排除问题。
当前已核对的正式 3.1.0 实现仍有相关转换路径。处理时保留原始缺失位置与运算契约,不把开放修补或某个开发版本的改动写成所有安装环境都已修好。


