You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DataFrame.set_index()创建MultiIndex时0和1被转布尔值的问题

问题

使用DataFrame.set_index()将两列转换为MultiIndex时,原本的整数0和1被转换为布尔值False和True。

初始表格(注意idx2列的值):

|    | idx1   | idx2   |   val |
|---:|:-------|:-------|------:|
|  0 | A      |        |     1 |
|  1 | B      | False  |     2 |
|  2 | B      | True   |     3 |
|  3 | C      | 0      |     4 |
|  4 | C      | 1      |     5 |
|  5 | C      | 2      |     6 |
|  6 | C      | 3      |     7 |

执行df.set_index(['idx1', 'idx2'])后,第4、5行的整数0、1被转为布尔值:

|              |   val |
|:-------------|------:|
| ('A', '')    |     1 |
| ('B', False) |     2 |
| ('B', True)  |     3 |
| ('C', False) |     4 |  <<<< 应为 ('C', 0)
| ('C', True)  |     5 |  <<<< 应为 ('C', 1)
| ('C', 2)     |     6 |
| ('C', 3)     |     7 |

问题出现在pandas 1.5.3版本中,求原因及解决办法。

最小可复现示例(MWE):

#!/usr/bin/env python3
import pandas

df = pandas.DataFrame({
    'idx1': list('ABBCCCC'),
    'idx2': ['', False, True, 0, 1, 2, 3],
    'val': range(1, 8)
})

print(df.to_markdown())

df = df.set_index(['idx1', 'idx2'])
print(df.to_markdown())
原因分析

这是因为idx2列是混合类型(包含字符串、布尔值、整数),pandas创建DataFrame时会将该列推断为object类型,但构建MultiIndex时,会尝试统一索引值的类型。由于Python中bool是int的子类,布尔值False/True和整数0/1等价,pandas会优先将0/1转换为对应的布尔值,以保持索引类型的一致性。

解决办法

有两种可靠方式避免该问题:

方法1:将idx2列统一转换为字符串类型

设置索引前,把idx2的所有值转为字符串,这样0、1会被保留为字符串"0"、"1",不会被转成布尔值:

df['idx2'] = df['idx2'].astype(str)
df = df.set_index(['idx1', 'idx2'])

转换后的索引会显示为('C', '0')、('C', '1'),完全保留原始值的字面形式。

方法2:使用Categorical类型固定值的类型

如果需要保留原始值的类型信息,可将idx2转为分类类型,强制pandas不自动转换类型:

df['idx2'] = pandas.Categorical(df['idx2'], categories=df['idx2'].unique())
df = df.set_index(['idx1', 'idx2'])

这种方式会保留每个值的原始类型,索引会正确显示为('C', 0)、('C', 1)。

内容的提问来源于stack exchange,提问作者buhtz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:25:22