【问题标题】:How can I map True/False to 1/0 in a Pandas DataFrame?如何在 Pandas DataFrame 中将 True/False 映射到 1/0?
【发布时间】:2013-06-27 07:29:47
【问题描述】:

我在 python pandas DataFrame 中有一个具有布尔值 True/False 值的列,但为了进一步计算,我需要 1/0 表示。有没有快速的pandas/numpy 方法来做到这一点?

【问题讨论】:

  • 还需要什么计算?
  • 鹦鹉@JonClements,为什么需要将bool转换为int才能用于计算? bool 直接与算术一起使用(因为它在内部是一个 int)。
  • @cs95 - Pandas 在内部使用 numpy bool,它们的行为可能略有不同。在普通 Python 中,True + True = 2,但在 Pandas 中,numpy.bool_(True) + numpy.bool_(True) = True,这可能不是您特定计算所需的行为。

标签: python pandas dataframe numpy boolean


【解决方案1】:

这是基于一些现有答案的可重现示例:

import pandas as pd


def bool_to_int(s: pd.Series) -> pd.Series:
    """Convert the boolean to binary representation, maintain NaN values."""
    return s.replace({True: 1, False: 0})


# generate a random dataframe
df = pd.DataFrame({"a": range(10), "b": range(10, 0, -1)}).assign(
    a_bool=lambda df: df["a"] > 5,
    b_bool=lambda df: df["b"] % 2 == 0,
)

# select all bool columns (or specify which cols to use)
bool_cols = [c for c, d in df.dtypes.items() if d == "bool"]

# apply the new coding to a new dataframe (or can replace the existing one)
df_new = df.assign(**{c: lambda df: df[c].pipe(bool_to_int) for c in bool_cols})

【讨论】:

    【解决方案2】:

    这个问题特别提到了一个列,因此当前接受的答案有效。但是,它不能推广到多列。对于那些对通用解决方案感兴趣的人,请使用以下内容:

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

    这适用于包含许多不同类型的列的 DataFrame,无论有多少是布尔值。

    【讨论】:

      【解决方案3】:

      我不得不将 FAKE/REAL 映射到 0/1,但找不到正确的答案。

      请在下面找到如何将具有 FAKE/REAL 值的列名“类型”映射到 0/1
      (注意:类似的可以应用于任何列名和值)

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

      【讨论】:

      • 简单得多:df['type'] = df['type'].map({'REAL': 1, 'FAKE': 0})。无论如何,我不确定它与这个问题是否太相关。
      • 感谢您提供更简单的解决方案。正如我在回答中提到的,我试图为略有不同的问题找到解决方案,并且只有类似的问题可用。希望我的回答和您的解决方案将来能对某人有所帮助。
      • 还有其他问题已经涵盖了这一点,例如stackoverflow.com/q/20250771
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 极端情况是somecolumn 中有 NaN 值。然后使用astype(int) 将失败。在保留 NaN 值的同时将 True 转换为 1.0 并将 False 转换为 0.0(浮点数)的另一种方法是:df.somecolumn = df.somecolumn.replace({True: 1, False: 0})
        • @DustByte 不错!
        • @DustByte 你不能只使用astype(float) 并获得相同的结果吗?
        • 如果值为文本和小写“true”或“false”,则首先执行 astype(bool].astype(int) 并且转换将起作用。Sas 输出为 bools 为小写 true 和假的。
        • 如何将其应用于多个列?
        【解决方案6】:

        您可以对数据框使用转换:

        df = pd.DataFrame(my_data condition)
        

        在 1/0 中转换真/假

        df = df*1
        

        【讨论】:

        【解决方案7】:

        只需将您的 Dataframe 乘以 1 (int)

        [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
        

        【讨论】:

        • 这个方案有什么优势?
        • @AMC 没有,这是一种 hacky 方式。
        • @AMC 如果您的数据框在布尔值旁边有 float 类型,则此方法不会破坏它们,df.astype(int) 会。而且由于它很hacky,因此使用# bool -> int 之类的评论来明确意图可能是一个好主意。
        • data * 1 用于混合类型的data + 0 有一个优势——它也适用于字符串,其中data + 0 会引发错误。等效的性能。
        • 优点:略短
        【解决方案8】:

        您也可以直接在 Frames 上执行此操作

        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
        

        【讨论】:

          【解决方案9】:

          True 在 Python 中是 1,同样False0*:

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

          您应该能够对它们执行任何您想要的操作,只需将它们视为数字,因为它们数字:

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

          因此,无需工作即可回答您的问题 - 您已经拥有所需的内容。

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

          【讨论】:

          • 如果进行浮点数学运算,请注意数据类型:np.sin(True).dtype 对我来说是 float16。
          • 我有一个带有布尔列的数据框,我可以调用df.my_column.mean() 就好了(正如你暗示的那样),但是当我尝试时:df.groupby("some_other_column").agg({"my_column":"mean"}) 我得到DataError: No numeric types to aggregate,所以它似乎它们总是相同的。仅供参考。
          • 在 pandas 版本 24(可能更早)中,您可以很好地聚合 bool 列。
          • 看起来 numpy 也会抛出布尔类型的错误:TypeError: numpy boolean subtract, the -` 运算符已被弃用,请改用 bitwise_xor、^ 运算符或logical_xor 函数。` 使用@User 的答案解决这个问题。
          • 另一个不一样的原因:df.col1 + df.col2 + df.col3 不适用于bool 列,因为它适用于int
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-31
          相关资源
          最近更新 更多