如何在Pandas DataFrame中将True/False映射为1/0?

293

我在Python的pandas数据框中有一个列,其中包含布尔值True/False,但是为了进行进一步计算,我需要将它们表示为1/0。是否有快速的pandas/numpy方法来实现这个目标?


2
还需要进行哪些进一步的计算? - Jon Clements
1
跟随 @JonClements 的说法,为什么需要将布尔型转换为整型才能进行计算?布尔型可以直接进行算术运算(因为它在内部实际上是一个整型)。 - cs95
3
@cs95 - Pandas在内部使用numpy bools,它们的行为可能会有所不同。在普通的Python中,True + True = 2,但在Pandas中,numpy.bool_(True) + numpy.bool_(True) = True,这可能不是您特定计算所期望的行为。 - sql_knievel
2
我需要它是因为statsmodels不允许在逻辑回归中使用布尔数据。 - Peter B
13个回答

544

将单个布尔值列简洁地转换为整数值 1 或 0 的方法:

df["somecolumn"] = df["somecolumn"].astype(int)

37
如果somecolumn中存在NaN值,使用astype(int)将会失败。另一种方法是将True转换为1.0,将False转换为0.0(浮点数),同时保留NaN值:df.somecolumn = df.somecolumn.replace({True: 1, False: 0}) - DustByte
@DustByte 很好的发现! - Homunculus Reticulli
1
@DustByte你不能使用astype(float)获得相同的结果吗? - AMC
如果值是文本且为小写的“true”或“false”,则首先执行astype(bool].astype(int),转换将起作用。SAS输出将bools作为小写的true和false。 - Golden Lion
这个如何应用到多列? - unaied
显示剩余2条评论

94

将您的数据框(Dataframe)乘以1(整数)即可。

[1]: data = pd.DataFrame([[True, False, True], [False, False, True]])
[2]: print data
          0      1     2
     0   True  False  True
     1   False False  True

[3]: print data*1
         0  1  2
     0   1  0  1
     1   0  0  1

1
这个解决方案有哪些优势? - AMC
7
@AMC:并没有什么好的方法,这只是一种折中的方式来实现它。 - Phillip Copley
2
如果你的数据框中除了布尔类型之外还有float类型,那么这种方法不会破坏它们,而df.astype(int)则会。由于这是一种hacky的方法,最好在注释中明确表明意图,比如# bool -> int - Dmitriy Work
2
使用 data * 1 而不是 data + 0 在混合类型时有一个优点 - 它也适用于字符串,而 data + 0 则会抛出错误。在性能方面等效。 - Dmitriy Work
优点:稍微更短。 - qwr

54

这个问题特指单列,因此目前被接受的答案可行。但是,它不能推广到多列。对于那些对通用解决方案感兴趣的人,请使用以下方法:

df.replace({False: 0, True: 1}, inplace=True)

对于包含许多不同类型列的DataFrame,无论其中有多少个是布尔值,此方法均有效。


49

True在Python中等同于1,同样地,False也等同于0*:

>>> True == 1
True
>>> False == 0
True

只需将它们视为数字,您就应该能够执行任何操作,因为它们本质上就是数字:


>>> issubclass(bool, int)
True
>>> True * 5
5

回答你的问题,不需要任何工作 - 你已经拥有了你正在寻找的东西。

* 注意我使用is作为英语单词,而不是Python关键字is - True将不会是任何随机1相同的对象。


2
如果进行浮点数运算,请注意数据类型:对我来说,np.sin(True).dtype 是float16。 - jorgeca
9
我有一个带有布尔类型列的数据框,我可以调用 df.my_column.mean() 很好地工作(正如你所暗示的那样),但是当我尝试:df.groupby("some_other_column").agg({"my_column":"mean"}) 时,我会得到 DataError: No numeric types to aggregate,因此它们似乎并不总是相同。仅供参考。 - dwanderson
在pandas 24版本(以及之前版本),您可以很好地聚合“bool”列。 - BallpointBen
1
看起来numpy在布尔类型方面也会抛出错误:TypeError: numpy boolean subtract, the -operator, is deprecated, use the bitwise_xor, the^ operator, or the logical_xor function instead. 使用@User的答案可以解决这个问题。 - Amadou Kone
1
另一个原因是不同的:对于 bool 列,df.col1 + df.col2 + df.col3 的工作方式与 int 列不同。 - colorlace

23

你也可以直接在画框上完成这个操作

In [104]: df = DataFrame(dict(A = True, B = False),index=range(3))

In [105]: df
Out[105]: 
      A      B
0  True  False
1  True  False
2  True  False

In [106]: df.dtypes
Out[106]: 
A    bool
B    bool
dtype: object

In [107]: df.astype(int)
Out[107]: 
   A  B
0  1  0
1  1  0
2  1  0

In [108]: df.astype(int).dtypes
Out[108]: 
A    int64
B    int64
dtype: object

4

使用 Series.view 将布尔值转换为整数:

df["somecolumn"] = df["somecolumn"].view('i1')

2
如果该列属于对象类型,例如你想将其转换为整数类型: df["somecolumn"] = df["somecolumn"].astype(bool).astype(int)

请确保将代码放在代码块中。 - Blue Robin

2

经过尝试和测试:

df[col] = df[col].map({'True': 1,'False' :0 })

如果有多个带有True/False的列,请使用以下代码。

for col in bool_cols:
    df[col] = df[col].map({'True': 1,'False' :0 })

@AMC 在评论中写下了这句话


2

我需要把FAKE/REAL映射成0/1,但找不到合适的答案。

请看下面如何将值为FAKE/REAL的列名"type"映射为0/1
(注意:类似的方法可以应用到任何列名和取值中)

df.loc[df['type'] == 'FAKE', 'type'] = 0
df.loc[df['type'] == 'REAL', 'type'] = 1

2
更简单的做法是:df['type'] = df['type'].map({'REAL': 1, 'FAKE': 0})。不过,我不确定这是否与本问题相关。 - AMC
感谢提供更简单的解决方案。正如我在答案中提到的,我试图找到一个稍微不同的问题的解决方案,只有类似这样的问题可用。希望我的答案和你的解决方案能够帮助未来的某个人。 - kaishu
有其他已经涵盖了这个问题的问题,比如 https://dev59.com/nGIj5IYBdhLWcg3weEwJ。 - AMC

2
您可以使用转换来处理您的数据框:
df = pd.DataFrame(my_data condition)

将True/False转换为1/0

df = df*1

1
这与3年前发布的此解决方案完全相同。 - AMC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接