首页 > 解决方案 > Pandas:用布尔值替换会产生不一致的结果

问题描述

我有一个数据框,它由类似的复选标记组成xv我用以下行替换为布尔值:

df.replace({'v': True, 'x': False}, inplace=True)

在运行之前df.replace()根据df.dtypes是所有列的类型object。毕竟replace()所有其他列仍然是object除了一个 bool 类型的列,并且其中的值是 type numpy.bool_。Pycharm 以红色背景显示此特定列,表示 True 值,如下所示。

熊猫布尔数据框

为什么会发生这种情况?不object适合存储布尔值吗?为什么要将此单列pandasdtypefromobject更改为?bool究竟是什么控制它,我如何强制将 dtype 保持为object

是否有理由将所有列pandas.np.bool改为,例如出于性能原因?

标签: pythonpandasboolean

解决方案


Pandas 在内部将系列存储为 NumPy 数组。当一个系列有混合类型时,Pandas / NumPy 必须做出决定:它选择一个包含该系列中所有类型的类型。举个简单的例子,如果你有一系列具有 type 的整数int并将单个值更改为float,那么你的系列将变为 type float

在此示例中,您的第 0 和第 2 系列具有NaN值。现在NaN,或被np.nan认为是float(尝试type(np.nan),这将返回float),而True/False被认为是布尔值。NumPy 可以存储这些值的唯一方法是使用 dtype object,它只是一堆指针(很像一个列表)。

另一方面,您的第一列只有布尔值,可以使用 type 存储bool。这里的好处是因为你没有使用指针集合 NumPy 可以为这个数组分配一个连续的内存块。这将产生相对于object系列或list.

您可以自己测试以上所有内容。这里有些例子:

s1 = pd.Series([True, False])
print(s1.dtype)  # bool

s2 = pd.Series([True, False, np.nan])
print(s2.dtype)  # object

s3 = pd.Series([True, False, 0, 1])
print(s3.dtype)  # object

最后一个例子很有趣,因为在 Python 中True == 1False == 0两者都返回True,因为bool可以认为是int. 因此,在内部,Pandas / NumPy 已决定不强制执行此相等性并选择其中一个。这样做的必然结果是,建议您在处理混合类型时检查您的系列的类型。

另请注意,当您更新值时,Pandas 会对 dtypes 进行检查:

s1 = pd.Series([True, 5.4])
print(s1.dtype)  # object

s1.iloc[-1] = False
print(s1.dtype)  # bool

推荐阅读