Pandas:用布尔值替换会产生不一致的结果

时间:2018-06-10 22:25:04

标签: python pandas boolean

我有一个数据框,其中包含xv等复选标记,我将使用以下行替换为布尔值:

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

在运行df.replace()之前,根据df.dtypes的所有列的类型为object。在replace()之后,所有其他列仍为object,但单个列的类型为bool,其中的值为numpy.bool_类型。 Pycharm显示此特定列,红色背景为True值,如下所示。

pandas boolean dataframe

为什么会发生这种情况? object不适合存储布尔值吗?为什么pandas会将dtypeobject更改为bool?究竟是什么控制它以及如何强制将dtype保持为object

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

1 个答案:

答案 0 :(得分:3)

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

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

另一方面,您的第一列只有布尔值,可以使用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