Pandas中字符串与分类数据类型的异常筛选行为求助
问题分析:分类与字符串类型筛选结果差异的原因
核心差异:缺失值(NaN)的比较逻辑不同
你的问题本质是pandas中分类(Categorical)类型和字符串(String)类型对NaN的比较规则不一致,导致相同筛选条件返回不同结果。
先拆解你的筛选条件
筛选逻辑是:
(data.partner != 'A') | ((data.brand == 'A') & (data.status == 'confirmed'))
其中右侧(data.brand == 'A') & (data.status == 'confirmed')在两种类型下结果完全一致——因为你的brand列从始至终都没有'A'这个值,所以这部分条件的结果全为False,最终筛选逻辑等价于仅判断data.partner != 'A'。
两种类型的关键差异点
1. 分类类型(Categorical)的行为
当你将partner设为分类类型时:
- 对于NaN值,
partner != 'A'会返回True——因为NaN不属于'A'这个类别,pandas判定其不等于'A'。 - 因此筛选结果会保留所有
partner为NaN和'C'的行,共6行,对应你第一张输出图。
2. 字符串类型(String)的行为
当你将partner转为字符串类型时:
- 对于NaN值,
partner != 'A'会返回NaN——pandas中字符串类型与NaN的任何比较都会返回NaN,而布尔索引会将NaN视为False。 - 因此筛选结果仅保留
partner为'C'的行,共3行,对应你第二张输出图。
解决方案:统一缺失值处理逻辑
如果需要让字符串类型的筛选结果和分类类型一致,需要显式包含NaN的情况:
方法1:显式判断NaN
test2 = data.loc[(data.partner != 'A') | data.partner.isna() | ((data.brand == 'A') & (data.status == 'confirmed'))]
方法2:使用isin反向判断
test2 = data.loc[~data.partner.isin(['A']) | ((data.brand == 'A') & (data.status == 'confirmed'))]
~data.partner.isin(['A'])会同时匹配NaN和非'A'的值,和分类类型的partner != 'A'行为一致。
内容的提问来源于stack exchange,提问作者FábioRB
相关产品推荐
相关产品推荐

