分类数据是常见的数据模型,这些值主要集中在围绕数据实体的属性和描述的相关字段和变量中。
(1)分类数据:分类数据指某些数据属性只能归于某一类别的非数值型数据,例如性别中的男和女就是分类数据。分类数据中的值没有明显的高、低、大、小等包含等级、顺序、排序、好坏等逻辑的划分,只是用来区分两个或多个具有相同或相当价值的属性。例如性别、颜色,它们都是相同衡量维度上的不同属性分类而已。
(2)顺序数据:顺序数据只能归于某一有序类别的非数值型数据,例如用户的价值度分为高、中、低;学历分为博士、硕士、学士,这些都属于顺序数据。在顺序数据中,有明显的排序规律和逻辑层次的划分。
运用标志方法处理分类和顺序数据
分类数据和顺序数据要参与模型计算,通常都会转化为数值型数据。将非数值型数据转换位数值型数据的最佳方法是:将所有分类或顺序变量的值域从一列多值的形态转换为多列只包含真值的形态,其中的真值可通过True、False或0、1的方式来表示,这种标志转换的方法有时候也称为真值转换,以用户性别为例,原有的用户数据如表1所示,经过准换后如表2所示。
用户ID | 用户性别 |
3566841 | 男 |
6541227 | 女 |
3512441 | 女 |
用户ID | 用户性别-男 | 用户性别-女 |
3566841 | 1 | 0 |
6541227 | 0 | 1 |
3512441 | 0 | 1 |
代码实操:Python标志转换
(1)自定义转换
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
df=pd.DataFrame({'id':[3566841,6511227,3512441],
'sex':['male','female','female'],
'level':['high','low','middle']})
#自定义转换主过程
df_new=df.copy()
for col_num,col_name in enumerate(df): #循环读出每个列的索引值和列名
col_data=df[col_name] #获得每列数据
col_dtype=col_data.dtype #获得每列的dtype类型
if col_dtype=='object': #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)
--------------------------------------------------------------------------------------
df:(转换前)
id sex level
0 3566841 male high
1 6511227 female low
2 3512441 female middle
df_new:(转换后)
id sex_male sex_female level_high level_low level_middle
0 3566841 True False True False False
1 6511227 False True False True False
2 3512441 False True False False True
在for循环中使用enumerate()方法,返回可供迭代的列索引和列名,然后获得每列数据和对应的dtype类型,用来做是否标志转换的条件判断。
(2)使用sklearn转换
df2=pd.DataFrame({'id':[3566841,65411227,3512441],
'sex':[1,2,2],
'level':[3,1,2]})
#使用sklearn进行标志转换
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) #组合为数据框
df2_all.columns=["id","sex_male","sex_female","level_low","level_middle","level_high"]
df2_all
---------------------------------------------------------------------------------------
df2:(转换前)
id sex level
0 3566841 1 3
1 65411227 2 1
2 3512441 2 2
df2_all:(转换后)
id sex_male sex_female level_low level_middle level_high
0 3566841 1.0 0.0 0.0 0.0 1.0
1 65411227 0.0 1.0 1.0 0.0 0.0
2 3512441 0.0 1.0 0.0 1.0 0.0
采用sklearn.preprocessing中的OneHotEncoder方法进行标志转换。其中获得ID列和转换后的列做拼接,便于数据格式的还原和对照;toarray方法输出为矩阵,如果不使用toarray进行转换,那么数据输出是一个3行5列的稀疏矩阵。