离散特征的编码分为2种情况:
1.我们在进行那些有大小关系的变量离散,小雨,中雨,大雨,
{“小雨”:1,“中雨”:2,“雨天”:3},这里面有一定数量的大小关系,这种映射的讲解在法1:标签的处理
2.只是换个名字的标签处理晴天,阴天,雨天这种标签没有大小的关系,那就考虑one-hot编码,或者说产生哑变量。
比如说,分数,需要将数据划分为“0到60”,“61到79”,“79到100”几个分数组。用的是pd.cut(data,bins),这里的data是我们要分割的分数数据,bins是[0,60,79,100]。类似函数可学习pd.qcut
import pandas as pd
df = pd.dataframe({"key":['green','red', 'blue'],
"data1":['a','b','c'],"sorce": [33,61,99]})
bins=[0,61,80,100]
cats=pd.cut(df["sorce"],bins)
print(cats)
group_name=["不及格","及格","优秀"]
cats2=pd.cut(df["sorce"],bins,labels=group_name,right=false)
#df["sorce"]为数据
#bins指定划分
#right指定区间闭合方向
#labels指定切分结果的标签
print(cats2)
############结果
0 (0, 61]
1 (0, 61]
2 (80, 100]
name: sorce, dtype: category
categories (3, object): [(0, 61] < (61, 80] < (80, 100]]
0 不及格
1 及格
2 优秀
name: sorce, dtype: category
categories (3, object): [不及格 < 及格 < 优秀]
那我们可以设计0-60分的需要编码为1,61-79为合格,80-100为优秀,这个和上面的第一条类似,只是需要一个数据划分的步骤,详见法2的相关处理。
pd.cut(data,4,precision=2) ,根据最大值与最小值计算等长面元长度。将数据分成4组(无法使各个面元中含有相同数量的数据点)精确度2位小数。
pd.qcut(data,[0,0.1,0.5,0.9,1]),根据样本分位数bins对数据进行面元划分,设置的是自定义分位数,0到1之间的数值,包含端点
#建立对应关系
label2current_service = dict(zip(range(0, len(set(df['current_service']))), sorted(list(set(df['current_service'])))))
current_service2label = dict(zip(sorted(list(set(df['current_service']))), range(0, len(set(df['current_service'])))))
# 原始数据的标签映射
df['current_service'] = df['current_service'].map(current_service2label)
#df['current_service']是一列代表类别的数据,上面是重新编码
from sklearn import svm
clf = svm.svc(decision_function_shape='ovr')
clf.fit(x_traindata, df['current_service'])
y_test_predict = model.predict(x_testdata)
y_test_predict_dateframe=pd.dataframe(y_test_predict,columns=["predict"],index=x_testdata.index)
#标签还原
y_test_predict_dateframe['predict'] = y_test_predict_dateframe['predict'].map(label2current_service)
上面是一个数据处理,模型训练,预测比较完整的处理流程,如果需要更明了一点的可参考:官方文档
#-*-coding=utf-8-*-
import pandas as pd
df = pd.dataframe([
['green', 'm', 10.1, 'class1'],
['red', 'l', 13.5, 'class2'],
['blue', 'xl', 15.3, 'class1']])
df.columns = ['color', 'size', 'prize', 'class label']
size_mapping = {
'xl': 3,
'l': 2,
'm': 1}
df['size'] = df['size'].map(size_mapping)
class_mapping = {label:idx for idx,label in enumerate(set(df['class label']))}
df['class label'] = df['class label'].map(class_mapping)
print('----------------------------------------------------------------')
print(df)
参考来源:https://blog.csdn.net/dongyanwen6036/article/details/78555163
这个结果第一个显示的是法1 ,映射的编码。下面的结果是法2,pandas 有一个get_dummies函数。具体见法2的介绍
将分类变量装换为“哑变量矩阵”(dummy matrix).如果dataframe的某一列中含有k个不同的值,则可以派生出一个k列矩阵或者dataframe(其值全为0和1)。pandas 有一个get_dummies函数可以实现该功能(当然自己动手也可以哒)
参考:利用python进行数据分析 第七章
pandas.
get_dummies
(data, prefix=none, prefix_sep='_', dummy_na=false, columns=none, sparse=false, drop_first=false, dtype=none)[source]¶
#!/ mypython
# -*- coding: utf-8 -*-
# @time : 2018/9/15 21:19
# @author : linyimeng
# @file : ceshi.py
# @software: pycharm
import pandas as pd
df = pd.dataframe({"key":['green','red', 'blue'],
"data1":['a','b','c'],"sorce": [33,61,99]})
# get_dummies(data,....) 在不指定新列的列名的情况下,将以data原标签对为列名
print("-------df---------")
print(df)
df_dummies1 =pd.get_dummies(df["key"])
print('''-------pd.get_dummies(df["key"])--df_dummies1-------''')
print(df_dummies1)
#prefix参数可以给哑变量的名字加上一个前缀
df_dummies2 =pd.get_dummies(df["key"],prefix="key")
print('''---=pd.get_dummies(df["key"],prefix="key")----df_dummies2-----''')
print(df_dummies2)
#如果不指定data列的话,默认是所有的分类变量进行one_hot处理
df_dummies3 =pd.get_dummies(df)
print("-------pd.get_dummies(df)---df_dummies3------")
print(df_dummies3)
#prefix参数可以给哑变量的名字加上一个前缀,如果是多个则需要一个列参数
df_dummies4 =pd.get_dummies(df,prefix=["class","like"])
print('''-------pd.get_dummies(df,prefix=["class","like"])----df_dummies4-----''')
print(df_dummies4)
df_dummies5 =pd.get_dummies(df,columns=["key","sorce"])
print('''---=pd.get_dummies(df,columns=["key","sorce"])----df_dummies5-----''')
print(df_dummies5)
同时在pandas可以指定 columns参数,pd.get_dummies(df,columns=["key","sorce"])指定被编码的列,返回被编码的列和不被编码的列;prefix参数可以给哑变量的名字加上一个前缀。
也可以类似的尝试: # 性别 data['sex'] = data['sex'].map({'female': 0, 'male': 1}).astype(int)
-------df---------
data1 key sorce
0 a green 33
1 b red 61
2 c blue 99
-------pd.get_dummies(df["key"])---df_dummies1------
blue green red
0 0.0 1.0 0.0
1 0.0 0.0 1.0
2 1.0 0.0 0.0
---=pd.get_dummies(df["key"],prefix="key")----df_dummies2-----
key_blue key_green key_red
0 0.0 1.0 0.0
1 0.0 0.0 1.0
2 1.0 0.0 0.0
-------pd.get_dummies(df)----df_dummies3-----
sorce data1_a data1_b data1_c key_blue key_green key_red
0 33 1.0 0.0 0.0 0.0 1.0 0.0
1 61 0.0 1.0 0.0 0.0 0.0 1.0
2 99 0.0 0.0 1.0 1.0 0.0 0.0
-------pd.get_dummies(df,prefix=["class","like"])---df_dummies4------
sorce class_a class_b class_c like_blue like_green like_red
0 33 1.0 0.0 0.0 0.0 1.0 0.0
1 61 0.0 1.0 0.0 0.0 0.0 1.0
2 99 0.0 0.0 1.0 1.0 0.0 0.0
---=pd.get_dummies(df,columns=["key","sorce"])----df_dummies5-----
data1 key_blue key_green key_red sorce_33 sorce_61 sorce_99
0 a 0.0 1.0 0.0 1.0 0.0 0.0
1 b 0.0 0.0 1.0 0.0 1.0 0.0
2 c 1.0 0.0 0.0 0.0 0.0 1.0
process finished with exit code 0
结合pd.cut,处理连续变量
bins=[0,61,80,100]
cats=pd.cut(df["sorce"],bins)
print(cats)
group_name=["不及格","及格","优秀"]
cats2=pd.cut(df["sorce"],bins,labels=group_name,right=false)
print(cats2)
print(pd.get_dummies(cats2,prefix="sorce"))# right是否是区间闭端
#prefix指定0-1编码后列名前缀
#结果
sorce_不及格 sorce_及格 sorce_优秀
0 1.0 0.0 0.0
1 0.0 1.0 0.0
2 0.0 0.0 1.0
合并():要注意使用merge还是join
#merge是因为两个合并的对象,有相同的列,merge以这些相同的列为索引进行合并。按照索引合并,就会出现两个sorce,不可以join
#join实现按索引合并,而不管他们有么有相同的列.同时可以指定on ="keyname',则把两个df 按照索引链接,并将原索引为新的“keyname”列,重新设置0,1,2..的索引
#join此处不可以,valueerror: columns overlap but no suffix specified: index(['sorce'], dtype='object')
#merge是因为两个合并的对象,有相同的列,merge以这些相同的列为索引进行合并。
df_new= pd.merge(df,df_dummies3)
print(df_new)
print(df_new.columns)
----------------
data1 key sorce data1_a data1_b data1_c key_blue key_green key_red
0 a green 33 1.0 0.0 0.0 0.0 1.0 0.0
1 b red 61 0.0 1.0 0.0 0.0 0.0 1.0
2 c blue 99 0.0 0.0 1.0 1.0 0.0 0.0
index(['data1', 'key', 'sorce', 'data1_a', 'data1_b', 'data1_c', 'key_blue',
'key_green', 'key_red'],
dtype='object')
----------------------
#merge此处不可以, 两个没有相同的列。pandas.tools.merge.mergeerror: no common columns to perform merge on
#join实现按索引合并,而不管他们有么有相同的列.同时可以指定on ="keyname',则把两个df 按照索引链接,并将原索引为新的“keyname”列,重新设置0,1,2..的索引
df_new= df.join(df_dummies6)
print(df_new)
print(df_new.columns)
-------------------
data1 key sorce sorce_不及格 sorce_及格 sorce_优秀
0 a green 33 1.0 0.0 0.0
1 b red 61 0.0 1.0 0.0
2 c blue 99 0.0 0.0 1.0
index(['data1', 'key', 'sorce', 'sorce_不及格', 'sorce_及格', 'sorce_优秀'], dtype='object')