Pandas修改category类型底层值dtype并保留category类型的方法
pandas将字符串类别的布尔分类列转换为原生布尔值分类列
问题场景
pandas DataFrame中存在一个category类型的列,底层存储值为字符串"True"/"False",而非原生布尔值True/False,存在以下问题:
- 调用
query等方法时必须写字符串匹配语句,例如df.query("field == 'True'"),写法繁琐 - 直接使用
df.astype({"field": bool})转换会丢失category类型,损失分类存储的内存效率优势,还会触发逻辑错误:非空字符串转布尔值永远为True,即字符串"False"会被错误转为True
可行方案
直接通过分类列的cat.rename_categories接口修改分类映射即可,全程保持列的category类型不变,仅更新分类标签的映射表,即使是千万级大表也几乎没有额外开销。
import pandas as pd # 构造测试样例 df = pd.DataFrame({ "field": pd.Categorical(["True", "False", "True", "False", "True"]) }) # 核心转换代码 df["field"] = df["field"].cat.rename_categories(lambda x: x == "True")
结果验证
执行以下代码确认转换符合预期:
# 验证dtype仍为category print(df["field"].dtype) # 输出: category # 验证分类值为原生布尔类型 print(df["field"].cat.categories) # 输出: Index([False, True], dtype='bool') # 验证query语法简化,无需再匹配字符串 print(df.query("field")) # 输出: # field # 0 True # 2 True # 4 True
注意事项
- 该方案不会修改分类列底层的整数编码,完全保留分类存储的内存优势,性能远高于“先转bool再转回category”的方案
- 如果你的列里布尔值的字符串表示不是
"True"/"False"(例如"是"/"否"、"1"/"0"),只需调整lambda里的判断逻辑适配即可 - 禁止直接对原列调用
.astype(bool):该操作会先把分类列转为普通object类型,不仅丢失类型优势,还会把所有非空字符串(包括"False")转为True,产生全列值为True的逻辑错误
内容的提问来源于stack exchange,提问作者william_grisaitis
相关产品推荐
相关产品推荐

