数据处理——数据变换
1哑变量处理
也叫独热编码,英文:One-hot Encoding。可将任意离散型数据变为0-1数值。
import pandas as pd df = pd.DataFrame({'性别':['男','女','男'], '学历':['本科','硕士','本科'], '民族':['汉族','仫佬族','维吾尔族']})
print(df)
学历 | 性别 | 民族 | |
---|---|---|---|
0 | 本科 | 男 | 汉族 |
1 | 硕士 | 女 | 仫佬族 |
2 | 本科 | 男 | 维吾尔族 |
哑变量函数:
pd.get_dummies(data, prefix=None, prefixsep='', dummy_na=False, columns=None, sparse=False, drop_first=False)
- data:进行哑变量处理的数据,无默认,不可省略
- prefix:前缀字符串
- prefixsep:连接字符串,默认为''
- dummy_na:表示是否将缺失值单独作为一类,默认为False,表示不将缺失值单独作为一类。
- columns:表示进行哑变量处理的列,仅接收list,默认所有的类别型的列。
- drop_first:表示是否剔除第一种类型,默认为False,表示不剔除。
# 初步简单调用 pd.get_dummies(df)
学历_本科 | 学历_硕士 | 性别_女 | 性别_男 | 民族_仫佬族 | 民族_汉族 | 民族_维吾尔族 | |
---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
2 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
# 修改column pd.get_dummies(df, prefix = 'x')
x_本科 | x_硕士 | x_女 | x_男 | x_仫佬族 | x_汉族 | x_维吾尔族 | |
---|---|---|---|---|---|---|---|
0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
2 | 1 | 0 | 0 | 1 | 0 | 0 | 1 |
# 修改连接符_和选择进行哑变量的列 pd.get_dummies(df, prefix_sep=':', columns=['学历'])
性别 | 民族 | 学历:本科 | 学历:硕士 | |
---|---|---|---|---|
0 | 男 | 汉族 | 1 | 0 |
1 | 女 | 仫佬族 | 0 | 1 |
2 | 男 | 维吾尔族 | 1 | 0 |
# 是否显示第一类 # 例如性别非男即女,所以只需一列便可说明 pd.get_dummies(df, prefix_sep=':', drop_first=True)
学历:硕士 | 性别:男 | 民族:汉族 | 民族:维吾尔族 | |
---|---|---|---|---|
0 | 0 | 1 | 1 | 0 |
1 | 1 | 0 | 0 | 0 |
2 | 0 | 1 | 0 | 1 |
2离散化
很多时候,我们用的某些算法(如:ID3决策树,Apriori算法,Kmeans算法等)都要求数据是离散的,包括上边讲到的哑变量处理,所以我们一般还需要先对其进行连续型数据的离散化。
离散化函数:
pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
- x:表示进行离散化的数据,只能是单独的某一列,或者Series。无默认,不可省略。
- bins:表示离散化后类别的数目。无默认,不可省略。
- right:是否包含最右边。bool,默认为True。
- labels:表示离散化后各个类别的标签,默认使用区间。
- retbins:是否返回bins。bool,默认为False。
- precision:bins的精度。int,默认为3。
- include_lowest:第一个左区间是否包含。bool,默认为False。(易引起ValueError或删除非唯一)
# 先输出连续型数据看看先 lsh = pd.DataFrame({'年龄':[18,16,15,17,19,28,80,55,36,43,12,23], '身高':[180,160,150,170,170,153,165,155,162,170,120,185]}) print(lsh)
年龄 | 身高 | |
---|---|---|
0 | 18 | 180 |
1 | 16 | 160 |
2 | 15 | 150 |
3 | 17 | 170 |
4 | 19 | 170 |
5 | 28 | 153 |
6 | 80 | 165 |
7 | 55 | 155 |
8 | 36 | 162 |
9 | 43 | 170 |
10 | 12 | 120 |
11 | 23 | 185 |
2.1等宽离散化
pd.cut(lsh['年龄'], bins=5, labels=['青少年','而立','不惑','耳顺','耄耋'])
0 青少年 1 青少年 2 青少年 3 青少年 4 青少年 5 而立 6 耄耋 7 耳顺 8 而立 9 不惑 10 青少年 11 青少年 Name: 年龄, dtype: category Categories (5, object): [青少年 < 而立 < 不惑 < 耳顺 < 耄耋]
pd.cut(lsh['年龄'], bins=5, precision=4, retbins=True)
(0 (11.932, 25.6] 1 (11.932, 25.6] 2 (11.932, 25.6] 3 (11.932, 25.6] 4 (11.932, 25.6] 5 (25.6, 39.2] 6 (66.4, 80.0] 7 (52.8, 66.4] 8 (25.6, 39.2] 9 (39.2, 52.8] 10 (11.932, 25.6] 11 (11.932, 25.6] Name: 年龄, dtype: category Categories (5, interval[float64]): [(11.932, 25.6] < (25.6, 39.2] < (39.2, 52.8] < (52.8, 66.4] < (66.4, 80.0]], array([11.932, 25.6 , 39.2 , 52.8 , 66.4 , 80. ]))
pd.cut(lsh['年龄'], bins=5, include_lowest=True)
0 (11.931000000000001, 25.6] 1 (11.931000000000001, 25.6] 2 (11.931000000000001, 25.6] 3 (11.931000000000001, 25.6] 4 (11.931000000000001, 25.6] 5 (25.6, 39.2] 6 (66.4, 80.0] 7 (52.8, 66.4] 8 (25.6, 39.2] 9 (39.2, 52.8] 10 (11.931000000000001, 25.6] 11 (11.931000000000001, 25.6] Name: 年龄, dtype: category Categories (5, interval[float64]): [(11.931000000000001, 25.6] < (25.6, 39.2] < (39.2, 52.8] < (52.8, 66.4] < (66.4, 80.0]]
2.2等频离散化
# 没现成,只能自定义函数 def Frequency_cut(data, k): ''' data:进行离散化的数据,只能是单独的某一列,或者Series k:分为几组,int型,无默认 ''' import numpy as np # 算出data的分位数 w = data.quantile(np.arrange(0, 1+1.0/k, 1.0/k)) # 将各分位数作为区间边界 data = pd.cut(data, w, include_lowest=True) return data
# 试运行,结果如下 Frequency_cut(lsh['身高'], 2)
0 (163.5, 185.0] 1 (119.999, 163.5] 2 (119.999, 163.5] 3 (163.5, 185.0] 4 (163.5, 185.0] 5 (119.999, 163.5] 6 (163.5, 185.0] 7 (119.999, 163.5] 8 (119.999, 163.5] 9 (163.5, 185.0] 10 (119.999, 163.5] 11 (163.5, 185.0] Name: 身高, dtype: category Categories (2, interval[float64]): [(119.999, 163.5] < (163.5, 185.0]]
2.3使用聚类模型进行离散化
def Kmeans_cut(data, k): from sklearn.cluster import KMeans #引入KMeans # 建立模型 kmodel = KMeans(n_clusters=k, n_jobs=4) # KMeans函数在下文有讲 # 训练模型 kmodel.fit(data.reshape((len(data), 1))) # 重塑data # 输出聚类中心并排序 c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0) # 0纵1横 # 相邻两项求中点,加上首末,作为边界点 w = pd.rolling_mean(c, 2).iloc[1:] # 问题:rooling_mean的使用 w = [0] + list(w[0]) + [data.max()] # 问题:为什么是w[0] data = pd.cut(data, w) return data
# 试一试,美滋滋 Kmeans_cut(lsh['年龄'], 5)
0 (0.0, 20.833] 1 (0.0, 20.833] 2 (0.0, 20.833] 3 (0.0, 20.833] 4 (0.0, 20.833] 5 (20.833, 32.5] 6 (67.5, 80.0] 7 (47.25, 67.5] 8 (32.5, 47.25] 9 (32.5, 47.25] 10 (0.0, 20.833] 11 (20.833, 32.5] Name: 年龄, dtype: category Categories (5, interval[float64]): [(0.0, 20.833] < (20.833, 32.5] < (32.5, 47.25] < (47.25, 67.5] < (67.5, 80.0]]
Last,简略讲一下KMeans函数。
# 有赋值的即为有默认值 def __init__(self, n_clusters=8, init='k-means++', n_init=10, max_iter=300, tol=1e-4, precompute_distances='auto', verbose=0, random_state=None, copy_x=True, n_jobs=1):
输入参数:
- n_clusters:要分成几类,即生成的质心数,int;
- init:初始化质心,function或array;
- n_init:设置初始化质心种子的次数,返回最好的一次,int;
- max_iter:每次迭代的最大次数,int;
- tol:容忍的最小误差,当误差小于tol时就会退出迭代,float;
- precompute_distances:权衡空间和时间,True时全放内存,auto时若样本小于12e6则True,其他相反,bool;
- verbose:是否输出详细信息,bool;
- random_state:随机生成器的种子,和初始化质心有关,int或numpy;
- copy_x:是否copy输入数据,为了不修改输入的数据,bool;(sklearn很多地方都有这个参数)
- n_jobs:并行数,即进程数量,与CPU有关,int。
输出参数:
- label_:每个类的标签;
- cluster_centers:每个类的中心,也叫聚类中心。(例子请看上边代码)
一个佛系的博客更新者,随手写写,看心情吧 (っ•̀ω•́)っ✎⁾⁾