get_dummies函数,特征工程转换DataFrame数据为独热码
发布于 作者:苏南大叔 来源:程序如此灵动~pandas.get_dummies()
是用在机器学习的特征工程处理方面的函数。主要的作用是:基于独热码的哑变量生成。其函数返回值表现形式上是和独热编码很类似,当然也有所不同。
苏南大叔的“程序如此灵动”博客,记录苏南大叔编程经验所学所想。本文测试环境:win10
,python@3.12.0
,pandas@2.1.3
。值得一提的是:OneHotEncoder()
来自sklearn
,而本文的get_dummies()
来自pandas
,细品。
独热码
前面的文章里面,可以把二维数据(包括DataFrame
)转为独热码。本文这里使用pandas.get_dummies()
来对dataframe
类型数据进行类似独热编码的转化。那么,这个基于独热码的哑变量生成的形式结果是什么呢?
对于数据:"大学、初中、高中"的独热码:
import numpy as np
from sklearn import preprocessing
one = preprocessing.OneHotEncoder()
X = np.array(["大学","初中","高中"]).reshape(-1,1)
a = one.fit_transform(X)
print(a.toarray())
'''
[[0. 1. 0.]
[1. 0. 0.]
[0. 0. 1.]]
'''
对比“基于独热码的哑变量”:
import numpy as np
from sklearn import preprocessing
X = np.array(["大学","初中","高中"]).reshape(-1,1)
import pandas as pd
a = pd.get_dummies(pd.DataFrame(X))
print(a)
'''
0_初中 0_大学 0_高中
0 False True False
1 True False False
2 False False True
'''
可见,两者还是非常相似的。参考文章:
哑变量
哑变量又叫做虚拟变量/虚设变量/名义变量,是人为设定的用于将分类变量引入回归模型中的方法。哑变量一般在回归问题的相关模型中经常使用。在是一种将多分类变量转换为二分变量的一种形式。如果多分类变量有k个类别,则可以转化为k-1个二分变量。虚拟变量的设置中:表示的基础类型、肯定类型取值为1;如果是比较类型,否定类型则取值为0。
比如学历、职业、性别等分类变量的数据是本身不能量化的,但是可以通过构造0和1的哑变量可以考察定性因素(分类变量)对因变量的影响。
函数原型
pandas.get_dummies(data, # 待处理数据
prefix=None, # 前缀
prefix_sep='_', # 和前缀的连接符
dummy_na=False, # 是否显示控制
columns=None, # 指定字段
sparse=False, # 是否表示为稀疏矩阵
drop_first=False, # 是否删除生成后的第一个字段
dtype=None) # 指定字段类型
其中的data
不仅仅可以是DataFrame
,还可以是Series
。例如:
import pandas as pd
a = pd.get_dummies(pd.DataFrame({
"edcuation":["大学","初中","高中"]
}))
print(a)
'''
edcuation_初中 edcuation_大学 edcuation_高中
0 False True False
1 True False False
2 False False True
'''
从结果上看,Series
的结果,似乎更加符合预期。但是,平时更常用的还是DataFrame
,毕竟一个数据集里面肯定是会有多个特征的,而Series
表示的就仅仅是一个特征。
import pandas as pd
b = pd.get_dummies(pd.Series(["大学","初中","高中"]))
print(b)
'''
初中 大学 高中
0 False True False
1 True False False
2 False False True
'''
基础测试代码
data
为DataFrame
还是Series
,对最终的结果影响还是很大的。最直观的感受是列名的默认组成不同。但是,整体来说,prefix
,prefix_sep
还是很好理解的。
下面的例子里面,还是以更常见的DataFrame
数据类型为例。
import pandas as pd
data = pd.DataFrame([
["虎子", "5", "dog"],
["老许", "3", "bird"],
],
columns = ["name", "age", "class"]
)
print(data)
'''
name age class
0 虎子 5 dog
1 老许 3 bird
'''
data2 = pd.get_dummies(data)
print(data2)
'''
name_老许 name_虎子 age_3 age_5 class_bird class_dog
0 False True False True False True
1 True False True False True False
'''
data3 = pd.get_dummies(data,columns=["class"])
print(data3)
'''
name age class_bird class_dog
0 虎子 5 False True
1 老许 3 True False
'''
data4 = pd.get_dummies(data,columns=["class"],prefix_sep='@')
print(data4)
'''
name age class@bird class@dog
0 虎子 5 False True
1 老许 3 True False
'''
# 下面这种情况,容易出现名字相同的特征列,不冲突但是影响理解。
data5 = pd.get_dummies(data,columns=["age","class"],prefix="#")
print(data5)
'''
name #_3 #_5 #_bird #_dog
0 虎子 False True False True
1 老许 True False True False
'''
dummy_na
dummy_na : bool
, default False 增加一列表示空缺值,如果False就忽略空缺值
import pandas as pd
_data = pd.DataFrame([
["虎子", "5", None],
["老许", "3", "cat"],
],
columns = ["name", "age", "class"]
)
data5 = pd.get_dummies(_data,columns=["age","class"],dummy_na=True)
print(data5)
'''
name age_3 age_5 age_nan class_cat class_nan
0 虎子 False True False False True
1 老许 True False False True False
'''
drop_first【常用】
drop_first : bool
, default False 获得k中的k-1个类别值,去除第一个,防止出现多重共线性。
如何理解“多重共线性”,这个待后续文章。这里简单的举例说的话,gender_male
和gender_female
实际上描述的是同一个事情,两个特征存在一个就可以。两者实际上是数据冗余的关系,这就是“多重共线性”。
当然,drop_first
也不是必须为true
。有的模型里面是需要为false
的。所以,这里要看模型的情况来定。
import pandas as pd
_data = pd.DataFrame([
["虎子", "5", None],
["老许", "3", "cat"],
],
columns = ["name", "age", "class"]
)
data5 = pd.get_dummies(_data,columns=["age","class"],drop_first=True)
print(data5)
'''
name age_5
0 虎子 True
1 老许 False
'''
这里对于class
列的处理有些特殊,首先没有设置dummy_na
,所以默认返回值是class_cat
,然后drop_first
又把class_cat
给删除了。
sparse 稀松数据
这个"稀松"无感啊,除非数据中存在大量的0
,才能偶尔感受到其区别。这里暂存。
data5 = pd.get_dummies(data,sparse=True)
print(data5)
print(data5.info)
dtype
似乎没有太多用途...
import pandas as pd
d = pd.DataFrame([
["虎子", "5", "dog"],
["老许", "3", "bird"],
],
columns = ["name", "age", "class"]
)
data = pd.get_dummies(d)
print(data)
'''
name_老许 name_虎子 age_3 age_5 class_bird class_dog
0 False True False True False True
1 True False True False True False
'''
data2 = pd.get_dummies(d,dtype=int)
print(data2)
'''
name_老许 name_虎子 age_3 age_5 class_bird class_dog
0 0 1 0 1 0 1
1 1 0 1 0 1 0
'''
data3 = pd.get_dummies(d,dtype=float)
print(data3)
'''
name_老许 name_虎子 age_3 age_5 class_bird class_dog
0 0.0 1.0 0.0 1.0 0.0 1.0
1 1.0 0.0 1.0 0.0 1.0 0.0
'''
结语
更多苏南大叔的经验文章,请点击:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。