2019独角兽企业重金招聘Python工程师标准>>>
封装的代码如下,文件名为my_one_hot_encoder.py
import pandas as pd
from sklearn.preprocessing import OneHotEncoder, LabelEncoder
class One_hot_encoder:
def __init__(self, df, column_name_list):
self.df = df
self.column_name_list = column_name_list
def multi_column_encoder(self):
Enc_ohe, Enc_label = OneHotEncoder(), LabelEncoder()
for column_name in self.column_name_list:
self.df["Dummies"] = Enc_label.fit_transform(self.df[column_name])
self.df_dummies = pd.DataFrame(Enc_ohe.fit_transform(self.df[["Dummies"]]).todense(), columns = Enc_label.classes_)
self.df_dummies.rename(columns=lambda x: column_name + "_" + x, inplace=True)
self.df = pd.concat([self.df, self.df_dummies], axis=1)
self.df.drop(["Dummies"], axis=1, inplace=True)
self.df.drop(self.column_name_list, axis=1, inplace=True)
return self.df
测试转换数据代码如下,文件名称为test_one_hot_encoder.py
import pandas as pd
from my_one_hot_encoder import One_hot_encoder
if __name__ == '__main__':
df = pd.read_excel("D:/data/testdata.xlsx")
column_name_list = ["pet", "city"]
df_encoded = One_hot_encoder(df, column_name_list).multi_column_encoder()
print(df_encoded)
##testdata.xlsx数据明细如下:
age city pet salary
4 beijing cat 4
6 shenzhen dog 5
3 guangzhou dog 1
3 shenzhen fish 1
##执行python test_one_hot_encoder.py,结果如下所示:
age salary pet_cat pet_dog pet_fish city_beijing city_guangzhou \
0 4 4 1.0 0.0 0.0 1.0 0.0
1 6 5 0.0 1.0 0.0 0.0 0.0
2 3 1 0.0 1.0 0.0 0.0 1.0
3 3 1 0.0 0.0 1.0 0.0 0.0
city_shenzhen
0 0.0
1 1.0
2 0.0
3 1.0
##LabelEncoder() & OneHotEncoder() 与get_dummies的利与弊
1、get_dummies 不像 sklearn 的 transformer一样,有 transform方法,所以一旦测试集中出现了训练集未曾出现过的特征取值,简单地对测试集、训练集都用 get_dummies 方法将导致数据错误。
2、不是 sklearn 里的transformer类型,所以得到的结果得手动输入到 sklearn 里的相应模块,也无法像 sklearn 的transformer一样可以输入到pipeline中 进行流程化地机器学习过程。
3、使用LabelEncoder() & OneHotEncoder()重新封装的方法,可以完美解决LabelEncoder不接受多列输入的问题,也解决了,在使用get_dummies时测试集中出现训练集未曾出现过的特征取值会报错的问题;当然重新封装的方法也可以进一步改成pipeline模式操作。