首页 > 解决方案 > 如何将系列中具有“无”值的熊猫类型转换为布尔值?

问题描述

为什么这个系列的值None会同时转换为TrueFalse

环境:

进口:

from IPython.display import display
import pandas as pd

转换NoneTrue

df_test1 = pd.DataFrame({'test_column':[0,1,None]})
df_test1['test_column'] = df_test1.test_column.astype(bool)
display(df_test1)

在此处输入图像描述

转换NoneFalse

df_test2 = pd.DataFrame({'test_column':[0,1,None,'test']})
df_test2['test_column'] = df_test2.test_column.astype(bool)
display(df_test2)

在此处输入图像描述

这是预期的行为吗?

标签: pythonpandastypesboolean

解决方案


是的,这是预期的行为,它源自dtype每个系列(列)的初始存储类型。第一个输入产生一系列浮点数,第二个包含对Python 对象的引用:

>>> pd.Series([0,1,None]).dtype
dtype('float64')
>>> pd.Series([0,1,None,'test']).dtype
dtype('O')

的浮点版本None是 NaN 或Not a Number,当解释为布尔值时转换为 True(因为它不等于 0):

>>> pd.Series([0,1,None])[2]
nan
>>> bool(pd.Series([0,1,None])[2])
True

在另一种情况下,原始None对象被保留,它转换为False

>>> pd.Series([0,1,None,'test'])[2] is None
True
>>> bool(None)
False

所以这归结为自动类型推断,Pandas 认为哪种类型最适合每一列;见DataFrame.infer_objects()方法。目标是最小化存储需求和操作性能;将数字存储为本机 64 位浮点值会导致更快的数字运算和更小的内存占用,同时仍然能够将“缺失”值表示为 NaN。

但是,当您传入数字和字符串的混合时,Panda 不能使用专用的专用数组类型,因此会退回到“Python 对象”类型,它是对原始 Python 对象的引用。

您可以明确指定要使用的类型,而不是让 Pandas猜测您需要什么类型。您可以使用其中一种可以为空的整数类型(而Pandas.NA不是 NaN);将这些转换为布尔值会导致缺失值转换为False

>>> pd.Series([0,1,None], dtype=pd.Int64Dtype).astype(bool)
0    False
1     True
2    False
dtype: bool

另一种选择是转换为可为空的布尔类型,从而保留None缺失数据的 /NaN 指示符:

>>> pd.Series([0,1,None]).astype("boolean")
0    False
1     True
2     <NA>
dtype: boolean

另请参阅用户手册中的处理缺失数据部分,以及可空整数可空布尔数据类型手册页。

请注意NA,表示缺失数据的值的 Pandas 概念仍然被认为是实验性的,这就是为什么它还不是默认值的原因。但是,如果您想为刚刚创建的数据框“选择加入”,您可以在创建框架后立即调用该DataFrame.convert_dtypes()方法

>>> df = pd.DataFrame({'prime_member':[0,1,None]}).convert_dtypes()
>>> df.prime_member
0       0
1       1
2    <NA>
Name: prime_member, dtype: Int64

推荐阅读