我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

pandas.get_dummies()是用在机器学习的特征工程处理方面的函数。主要的作用是:基于独热码的哑变量生成。其函数返回值表现形式上是和独热编码很类似,当然也有所不同。

苏南大叔:get_dummies函数,特征工程转换DataFrame数据为独热码 - 特征工程转化
get_dummies函数,特征工程转换DataFrame数据为独热码(图1-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔编程经验所学所想。本文测试环境:win10python@3.12.0pandas@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
'''

基础测试代码

dataDataFrame还是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_malegender_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
'''

结语

更多苏南大叔的经验文章,请点击:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   python