Python数据分析与运营实战
例3.2.3 Python标志转换
本例模拟有两列数据分别出现分类数据和顺序数据的情况,并通过自定义代码以及sklearn代码中的OneHoteEncoder及pandas中的get_dummies方法分别进行标志转换。
import pandas as pd
from sklearn.preprocessing import OneHotEncoder #导入OneHotEncoder库
#generate data
df = pd.DataFrame({'id':[3566841, 6541227, 3512441],
'sex':['male','Female','Female'],
'level':['high','low','middle']}) #按列赋值
#按行赋值
df_2 = pd.DataFrame([[3566841, 'male', 'high'],[6541227,'Female','low'],
[3512441,'Female','middle']],columns=['id','sex','level'])
print(df)
print(df_2)
#自定义转换主过程
df_new = df.copy() #复制一份新的数据框用来存储转换结果
for col_num, col_name in enumerate(df): #循环读出每个列的索引值和列名
col_data = df[col_name]
col_dtype = col_data.dtype
if col_dtype == 'object':
df_new = df_new.drop(col_name,1) #删除df 数据框中要进行标志转换的列
value_sets = col_data.unique() #获取分类和顺序变量的唯一值域
for value_unique in value_sets: #读取分类和顺序变量中的每个值
col_name_new = col_name + '_' + value_unique
col_tmp = df.iloc[:,col_num] #获取原始数据列
new_col = (col_tmp == value_unique) #将原始数据列与每个值比较,相同为True,否则为False
df_new[col_name_new] = new_col #为最终结果集增加新列值
print(df_new) #打印输出转换后的数据
#使用sklearn进行标志转换
df2 = pd.DataFrame({'id':[3566841, 6541227, 3512441],
'sex':[1, 2, 2],
'level':[3, 1, 2]})
id_data = df2.values[:, :1] #获得ID列
transform_data = df2.values[:, 1:] #指定要转换的列
enc = OneHotEncoder() #建立模型对象
df2_new = enc.fit_transform(transform_data).toarray() #标志转换
df2_all = pd.concat((pd.DataFrame(id_data), pd.DataFrame(df2_new)), axis=1)
print(df2_all)
print(df2_new)
#使用get_dummies方法进行转换,推荐用这种方法
df3 = pd.DataFrame({'id':[3566841, 6541227, 3512441],
'sex':['male','Female','Female'],
'level':['high','low','middle']}) #按列赋值
sex_df = pd.get_dummies( df3['sex'] , prefix='sex' )
df3 = pd.concat([df3,sex_df],axis=1)
print(df3)
df3.drop('sex',axis=1,inplace=True)
print(df3)
level_df = pd.get_dummies(df3['level'], prefix='level')
df3 = pd.concat([df3,level_df], axis=1)
df3.drop('level',axis=1,inplace=True)
print(df3)
为什么要对这种离散型的数据进行标志转换呢?作者在文章中给出了如下解释:
为什么不能直接用数字来表示不同的分类和顺序数据,而一定要做标志转换?
这是因为在用数字直接表示分类和顺序变量的过程中,无法准确还原不同类别信息之间的差异和相互关联性。例如:
- ·针对分类数据:性别变量的属性值是男和女,无论用什么值来表示都无法表达出两个值的价值相等且带有区分的含义。如果用1和2区分,那么1和2本身已经带有距离为1的差异,但实际上二者是不具有这种差异性的,其他任意数字都是如此;如果用相同的数字来表示,则无法达到区分的目的。
- ·针对顺序数据:学历变量的属性值是博士、研究生和学士,可以 用3-2-1来表示顺序和排列关系,那么如何表示三个值之间的差异是3-2-1而不是30-20-10或者1000-100-2呢?因此,任何一个有序数字的排序也 都无法准确表达出顺序数据的差异性