Pandas将分类列单元格设为np.nan时转float如何保留分类类型
问题原因
对Categorical类型序列使用apply方法返回np.nan做值替换时,apply会基于返回值重新推断数据类型,不会继承原序列的分类类型约束;又因为np.nan本质是浮点类型,整数与浮点值混合时Pandas会自动将整列类型提升为float64,最终丢失Categorical类型。
可行解决方案
- 方案1:布尔索引直接赋值(最推荐)
Categorical类型原生支持缺失值,无需使用apply遍历,直接通过条件筛选目标位置赋值即可保留分类类型:
import numpy as np import pandas as pd from pandas.api.types import CategoricalDtype s = pd.Series([1, 2, 2, 3, 2]) cat_type = CategoricalDtype(categories=[1, 2, 3], ordered=False) s_cat = s.astype(cat_type) # 筛选值大于2的位置赋值为np.nan s_cat.loc[s_cat > 2] = np.nan
执行后输出结果如下,类型保持为Categorical:
0 1 1 2 2 2 3 NaN 4 2 dtype: category Categories (3, int64): [1, 2, 3]
- 方案2:apply处理后手动转回原分类类型
如果业务逻辑必须依赖自定义函数+apply实现复杂判断,可在处理完成后,用预先定义的分类规则重新做类型转换:
def nanify(cell): if cell > 2: return np.nan return int(cell) s_result = s_cat.apply(nanify).astype(cat_type)
- 方案3:使用
Series.where实现条件替换Series.where会保留原序列的数据类型,符合条件的位置保留原值,不符合条件的位置替换为指定值:
# 保留小于等于2的值,其余替换为np.nan s_result = s_cat.where(s_cat <= 2, np.nan)
注意:Categorical类型的缺失值不需要提前加入
categories列表中,原有分类定义不会因为出现缺失值发生改变。
内容的提问来源于stack exchange,提问作者Ohm
相关产品推荐
相关产品推荐

