正确做法是用 df.astype(int) 将布尔列转为 0/1,对含 nan 的 boolean 类型需先 fillna() 或用 "int64";批量转换应向量化操作而非循环,避免链式赋值。

用 pandas.get_dummies() 处理布尔列会出错
直接对布尔型 Series 或 DataFrame 调用 pd.get_dummies(),默认会把 True/False 当作分类值展开成两列(如 col_False, col_True),这显然不是指示变量(indicator variable)的本意——我们只想要一列,值就是原布尔值本身(0/1)。更糟的是,如果列里只有 True 或只有 False,还会触发 ValueError: dummy variable columns must be >= 2。
正确做法是跳过 get_dummies(),改用类型转换:
-
df.astype(int)最快,直接把True→1、False→0,保留列名和结构 -
df * 1也行,但会隐式触发广播,对混合类型DataFrame不安全 - 避免
df.map({True: 1, False: 0}),它比astype(int)慢一个数量级
处理含 NaN 的布尔矩阵要小心
原始数据常含缺失值,而 pd.BooleanDtype(即 boolean 扩展类型)在 astype(int) 时会报错:TypeError: boolean value of NA is ambiguous。这不是 bug,是设计使然——NA 不能自动转为 0 或 1。
必须显式决定缺失值的映射逻辑:
- 填 0:用
df.fillna(False).astype(int) - 填 -1 或其他哨兵值:先
df = df.fillna(-1),再.astype(int)(注意确保原列无字符串) - 保持
NaN为浮点nan:用df.astype("Int64")(注意是大写I),得到可空整型,NA→<code>pandas.NA
批量转换多列时别用循环
有人习惯写 for col in bool_cols: df[col] = df[col].astype(int),在列数多(>50)、行数大(>100k)时明显变慢。Pandas 的向量化操作能一次处理整个子集:
- 选列转换:
df[bool_col_names] = df[bool_col_names].astype(int) - 自动识别布尔列:
bool_mask = df.dtypes == "bool",然后df.loc[:, bool_mask] = df.loc[:, bool_mask].astype(int) - 若混有
boolean类型,先统一转bool:df[bool_col_names] = df[bool_col_names].astype("boolean").astype(bool),再转int
性能对比:astype(int) vs numpy.where()
对超大布尔矩阵(千万行以上),df.astype(int) 底层调用的是 NumPy 的 asarray(),已足够快;但如果你已经用 np.array(df) 拿到纯 NumPy 数组,np.where(arr, 1, 0) 确实略快 5–10%,不过得承担内存拷贝开销和类型丢失风险。
真实场景中,99% 的情况直接 df.astype(int) 就够了。唯一要注意的是:别在链式赋值里用它,比如 df[["a","b"]].astype(int) 返回副本,不会修改原 df——必须显式赋值。
扩展类型、缺失值处理、向量化边界,这几个地方不留意,转出来的结果要么报错,要么语义错误,而且很难一眼发现。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











