数据处理——数据变换

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:每个类的中心,也叫聚类中心。(例子请看上边代码)

 

posted @ 2018-07-30 20:39  WoLykos  阅读(1685)  评论(0编辑  收藏  举报