数据预处理
通常获取数据通常都是不完整的,缺失值、零值、异常值等情况的出现导致数据的质量大打折扣,而数据预处理技术就是为了让数据具有更高的可用性而产生的,在本章中学习一下如何用Python进行数据预处理。
数据预处理是什么
当用户拿到一份新数据的时候,通过各种手段进行数值替换,空值填充等过程就是数据预处理。
本文中我们将会了解到的数据预处理方式有:
① 一般的数据预处理;
② 缺失值的处理;
③ 异常值的处理;
④ 数据变换方法;
⑤ 高级数据预处理方法;
⑥ 数据预处理实战。
重复数据的处理
数据采集人员在采集数据时,经常会发生采集到重复数据的情况。在Pandas中可以通过最基本的DataFrame创建方法来创造含有重复数据的数据集,进行修改操作。
1)构造一个含有重复数据的数据集,如以下代码所示。
import pandas as pd # 创建一个带有重复数据的DataFrame df = pd.DataFrame(data=[['a', 1], ['a', 2], ['a', 3], ['b', 1], ['b', 2], ['a', 1], ['a', 2]], columns=['label', 'num']) print(df)
运行结果:
label num 0 a 1 1 a 2 2 a 3 3 b 1 4 b 2 5 a 1 6 a 2
在运行结果中可以发现7条数据中存在着[‘a’, 1],[‘a’, 2]两组重复数据。
2)Pandas中提供了duplicated()函数用来查找数据集中是否存在重复数据。查找重复数据如以下代码所示。
df = pd.DataFrame(data=[['a', 1], ['a', 2], ['a', 3], ['b', 1], ['b', 2], ['a', 1], ['a', 2]], columns=['label', 'num']) df = df.duplicated() print(df)
运行结果:
0 False 1 False 2 False 3 False 4 False 5 True 6 True dtype: bool
并不需要如此多的运行结果,在判断是否含有重复数据的时候只需要知道“有”或者“没有”就可以了,使用any()函数去判断数据经过duplicated()函数后有没有重复值。
df = pd.DataFrame(data=[['a', 1], ['a', 2], ['a', 3], ['b', 1], ['b', 2], ['a', 1], ['a', 2]], columns=['label', 'num']) df = any(df.duplicated()) print(df)
运行结果:
True
这样对于数据中是否含有重复值就很容易知道了。
3)对于重复数据,不需要进行改动,只需要进行删除就可以,pandas中提供了drop_duplicates()函数来删除重复数据。处理重复数据如以下代码所示。
df = pd.DataFrame(data=[['a', 1], ['a', 2], ['a', 3], ['b', 1], ['b', 2], ['a', 1], ['a', 2]], columns=['label', 'num']) df.drop_duplicates(inplace=True) # df = df.drop_duplicates(inplace=False) print(df)
运行结果:
label num 0 a 1 1 a 2 2 a 3 3 b 1 4 b 2
在drop_duplicates()函数中,参数inplace=True表示在原数据集上进行操作,参数默认为False。
缺失值的处理
在分析数据的时候往往会遇到很多缺失的数据,该类型的数据严重影响数据分析的结果,本章讲述对于数据中缺失值的处理方法。
1.构造一个含有缺失值的数据集。
先创建一个普通的DataFrame,再通过reindex()函数去重构索引,创建出一个带有缺失值的DataFrame,其中(NaN即表示缺失值)如以下代码所示。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) # 使用chr()函数创建索引,chr()函数会将转换为ascii码对应的字符 df = df.reindex([chr(x).lower() for x in range(65, 72)]) # df = df.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g']) print(df)
结果如下:
1st 2nd 3rd a -1.083079 1.041412 -0.457510 b NaN NaN NaN c 1.719107 -0.033295 0.033539 d -1.366099 0.296715 0.416878 e 0.341656 0.332213 -0.620006 f NaN NaN NaN g -0.677747 0.930917 -0.254245
在Pandas中提供了isnull()函数判断所有位置的元素是否缺失,缺失显示True,不缺失显示False,如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) print(df.isnull()) # 数据量较多的时候可以查看前面几行。 # df.isnull().head()
结果如下:
1st 2nd 3rd a False False False b True True True c False False False d False False False e False False False f True True True g False False False
在实际的操作中并不需要展示出所有位置的结果,可以结合使用any()函数进行行(列)是否存在空值的判断,如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) print(df.isnull().any())
结果如下:
1st True 2nd True 3rd True dtype: bool
any()函数中可以传入axis参数进行行或列的空值判断,默认为axis=0也就是判断每一列中是否存在空值,axis=1时用于判断行。
如果想要统计每一行或列中含有空值的个数,可在any()函数的后面加入求和函数sum(),如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) print(df.isnull().any().sum())
结果如下:
3
2.缺失值的填补
缺失值的填补是在进行数据预处理过程中最重要的一环,同样缺失值填补的方法多种多样,需要考虑具体的某一种场景下用怎样的填补方法。
当数据集中出现某一列数据全都为缺失值,或者缺失值的占比很大并且业务上允许删除该属性列的时候。通常大于60%,可以考虑直接删除整列,如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) # 以删除2nd列为例 del df['2nd'] print(df)
结果如下:
1st 3rd a -0.610682 0.214314 b NaN NaN c 0.121638 -1.589455 d -0.321348 -0.792944 e 1.787892 -1.373090 f NaN NaN g 0.092022 1.086180
对于缺失值而言,只有少数的缺失值时可以直接删掉此行。对于含有大量缺失值的列可以直接进行列删除的处理,如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) # dropna中提供了参数axis,其中0代表行,1代表列 df = df.dropna(axis=0) print(df)
del方法和dropna()函数在删除列区别在于,del删除指定列,dropna删除含有缺失值的所有列。
结果如下:
1st 2nd 3rd a -0.001636 -0.462246 -0.630965 c -0.834343 -0.026846 -0.206404 d -0.924094 1.343112 2.162887 e 2.534455 1.207891 -0.801314 g -0.374566 0.904248 1.088779
指定数据填补缺失值,使用标量0来替换缺失值**。**在很多情况下都会用0来填充缺失值,比如对于一列表示婚龄的数据,若有很多缺失值,可以认为没有数据的是因为未结婚的人群无法选择一样,此时就可以用0来表示没结婚的人群的婚龄。
Pandas中的fillna()函数提供了填充缺失值的方法,该方法中不仅可以填充数值数据,也可以进行字符串的填充,如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) # dropna中提供了参数axis,其中0代表行,1代表列 df = df.fillna(0) print(df)
结果如下:
1st 2nd 3rd a -0.073320 -1.040557 0.625403 b 0.000000 0.000000 0.000000 c 0.259383 0.623854 -1.012501 d -0.929179 -0.071979 0.036534 e 0.454091 -0.940268 -0.130758 f 0.000000 0.000000 0.000000 g 0.808844 1.888317 1.410490
当缺失值所在的变量为数值型时,对于中位数填充只需要把均值填充, mean()函数改成median()函数即可用中位数来填补数据,如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) # dropna中提供了参数axis,其中0代表行,1代表列 df['2nd'] = df['2nd'].fillna(df['2nd'].median()) print(df)
结果如下:
1st 2nd 3rd a -1.478387 -0.392058 1.079640 b NaN -0.392058 NaN c -1.357133 -0.431554 -1.451272 d 0.255212 0.392723 0.035754 e -0.999840 -0.253316 1.549664 f NaN -0.392058 NaN g -1.258107 -1.468062 -1.773574
字符型数据填充方式:当缺失值为字符型数据时,通常用众数填充缺失值。pandas中的mode()函数来使用众数填补缺失值,如以下代码所示。
import pandas as pd import numpy as np import random # 使用随机的方法创建一个字符型的DataFrame df = pd.DataFrame( [random.choice(['apple', 'banana', 'orange', 'pear']) for i in range(15)]) # 转换DataFrame的形状为5*3 df = pd.DataFrame(df.values.reshape(5, 3)) df.index = ['a', 'c', 'd', 'e', 'g'] df.columns = ['1st', '2nd', '3rd'] df = df.reindex([chr(x).lower() for x in range(65, 72)]) # 使用众数来填充数据 df['2nd'] = df['2nd'].fillna(df['2nd'].mode()[0]) print(df)
结果如下:
1st 2nd 3rd a pear pear banana b NaN banana NaN c banana banana apple d banana orange banana e orange orange orange f NaN banana NaN g orange banana banana
random中的choice()函数去随机选择一些字符型数据生成一个DataFrame,再转换DataFrame的形状为5*3,最后使用pandas中的mode()函数来使用众数填补缺失值。其中mode()[0]表示在存在多种众数的情况下选取第一个值。
在Python中还提供了根据上(下)一条数据的值对缺失值进行填充,对于这种方式,只需要更改fillna()中的参数即可,如以下代码所示。
df = pd.DataFrame(np.random.randn(5, 3), index=['a', 'c', 'd', 'e', 'g'], columns=['1st', '2nd', '3rd']) df = df.reindex([chr(x).lower() for x in range(65, 72)]) # method参数为'pad'时,按照上一行进行填充 # method参数为'bfill'时,按照下一行进行填充 df= df.fillna(method='pad') print(df)
结果如下:
1st 2nd 3rd a -0.530551 -0.676573 1.140592 b -0.530551 -0.676573 1.140592 c -1.610111 1.253288 -0.174413 d -0.572878 0.771014 1.245265 e -0.078281 -0.348678 1.917448 f -0.078281 -0.348678 1.917448 g -0.579313 -0.909112 1.723621
异常值的处理
在异常值处理之前需要对异常值进行识别,一般多采用单变量散点图或是箱线图来达到异常值进行识别目的,利用图形来判断数值是否处于正常范围。
1.绘制箱线图查看异常值
箱线图中含有上边缘和下边缘,如果有数据点超出了上下边缘,就会把该类数据点看作是异常值,箱线图中包含内容如下图所示。
箱线属性描述:① 上四分位数(Q3):75%位置的数据值;② 下四分位数(Q1):25%位置的数据值;③ 四分位距:Δ \DeltaΔQ=Q3-Q1;④ 上边缘:Q3+1.5Δ \DeltaΔQ;⑤、下边缘:Q1-1.5Δ \DeltaΔQ。
示例1: 通过具体数据来通过箱线图查看缺失值。随机生成数据, 对于不同性别、不同年龄的特征(girl_20、boy_20、girl_30、boy_30)来表示男生、女生在20岁和30岁时的收入分布。随机创造70-100个符合正态分布的数据,绘制出对应的箱线图,如以下代码所示。
import numpy as np import matplotlib.pyplot as plt fig, ax = plt.subplots() # 子图 # 封装一下这个函数,用来后面生成数据 def list_generator(mean, dis, number): # normal分布,输入的参数是均值、标准差以及生成的数量 return np.random.normal(mean, dis * dis, number) # 生成四组数据用来做实验,数据量都为50 # 分别代表男生、女生在20岁和30岁的收入分布 girl_20 = list_generator(1000, 10.5, 50) boy_20 = list_generator(1500, 20.5, 50) girl_30 = list_generator(3000, 25.1056, 50) boy_30 = list_generator(5000, 29.54, 50) data = [girl_20, boy_20, girl_30, boy_30] # 用positions参数设置各箱线图的位置 ax.boxplot(data, positions=[ 0, 0.6, 3, 3.7, ]) # 设置x轴刻度标签 ax.set_xticklabels([ "girl20", "boy20", "girl30", "boy30", ]) plt.show()
运行结果样式如下图所示:
girl20和boy20两个属性中出现了在箱线图之外的圆圈,这就是这两个属性所存在的异常值。
2.异常值的处理方法
异常值处理方法:① 删除含有异常值的记录;② 视为缺失值来处理;③ 不处理。
根据指定数据的删除方法以及缺失值的处理方法,深入学习异常值转换成缺失值。
1)计算上边缘和下边缘
判断一下该列的上边缘和下边缘,如以下代码所示。
import numpy as np import pandas as pd # 封装一下这个函数,用来后面生成数据 def list_generator(mean, dis, number): # normal分布,输入的参数是均值、标准差以及生成的数量 return np.random.normal(mean, dis * dis, number) # 生成四组数据用来做实验,数据量都为50 # 分别代表男生、女生在20岁和30岁的收入分布 girl_20 = list_generator(1000, 10.5, 50) boy_20 = list_generator(1500, 20.5, 50) girl_30 = list_generator(3000, 25.1056, 50) boy_30 = list_generator(5000, 29.54, 50) data = [girl_20, boy_20, girl_30, boy_30] df = pd.DataFrame({ 'girl20': girl_20, 'boy20': boy_20, 'girl30': girl_30, 'boy30': boy_30 }) s = df.describe() print(s) print('-' * 50) # 基本统计量 q1 = s.loc['25%'][0] q3 = s.loc['75%'][0] iqr = q3 - q1 mi = q1 - 1.5 * iqr ma = q3 + 1.5 * iqr print('分位差为:%.3f,下限为:%.3f,上限为:%.3f' % (iqr, mi, ma))
运行结果:
girl20 boy20 girl30 boy30 count 50.000000 50.000000 50.000000 50.000000 mean 986.506573 1407.044007 3071.759102 4830.613134 std 101.910800 378.120218 618.421610 753.990111 min 692.472224 661.495150 1284.628225 2950.875322 25% 921.181027 1217.701326 2656.324485 4288.638289 50% 994.044804 1374.945995 3020.741556 4945.984804 75% 1056.785261 1553.945982 3351.613151 5306.243930 max 1213.199964 2802.276364 4447.697361 6257.073997 -------------------------------------------------- 分位差为:135.604,下限为:717.775,上限为:1260.192
在panndas中提供了describe()函数去查看基本的统计量,只需提取出gril20列对应的25%分位数和75%分位数即可,提取之后计算对应的上边缘和下边缘。
2)判断异常值并转换为缺失值
先使用筛选条件来找到异常值,如以下代码所示。
error = df[(df['girl20'] < mi) | (df['girl20'] > ma)] print(error) print('异常值共%i条' % len(error))
结果如下:
girl20 boy20 girl30 boy30 8 692.472224 2802.276364 2323.241344 4162.719777 异常值共1条
使用了pandas中的mask函数替换数据中2条异常值。该函数能够满足过滤条件的数据替换成想要的结果,以下代码所示。
df['girl20'] = df['girl20'].mask((df['girl20'] < mi) | (df['girl20'] > ma), None) print(df.loc[4]) print(df.loc[39])
结果如下:
girl20 853.304 boy20 1694.83 girl30 2582.11 boy30 5234.39 Name: 4, dtype: object girl20 1092.92 boy20 1314.35 girl30 2691.67 boy30 5815.37 Name: 39, dtype: object
把异常值全部转换为缺失值时,可以使用缺失值填补的方法进行数据的填补。
数据变换
一份完整的数据,数据上虽然没有缺失值,但是有一些数据并不是用户需要的形式,如字符型数据、数据间差异较大的数据等等,处理这些数据需要进行数据变换。
数据变换方法:数据类型转换,数据标准化处理(Z-score标准化),数据归一化处理(Min-Max标准化)。
数据归一化:数据归一化会将所有的数据约束到[0,1]的范围内。
转换数据类型
pandas中提供了map函数用于数据转换,通常将一些字符型数据转换为可以用于计算机计算的数值型数据。
示例1:根据”男”,”女”两种类型的数据,把数据中所有的”男”,”女”转换成数值类型1,0 ,如以下代码所示。
import pandas as pd data = {'性别': ['男', '女', '男', '女', '女']} df = pd.DataFrame(data) df[u'性别_new'] = df[u'性别'].map({'男': 1, '女': 0}) print(df)
结果如下:
性别 性别_new 0 男 1 1 女 0 2 男 1 3 女 0 4 女 0
数据标准化(Z-score标准化)
数据进行分析之前,通常需要先将数据标准化,利用标准化后的数据进行数据分析。数据标准化是一种将整列数据约束在某个范围内的方法,经过标准化处理,原始数据均转换为无量纲化指标测评值,即各指标值都处于同一个数量级别上,可以进行综合测评分析。
如果通过身高体重去分析一个正常身材的人的胖瘦,假设身高的衡量标准为“米”,而体重的衡量标准为“斤”,由于二者的数量级的差异,会导致判断胖瘦的标准发生改变,导致体重一项具有了更大的影响力 ,但是根据经验可以知道,一个正常身材人的胖瘦是由身高和体重共同决定的,对于这样的数据而言,给计算机使用的数据就要进行数据标准化。
数据标准化公式如下:
公式中μ 代表均值,σ 代表标准差。
使用numpy和pandas来实现标准化,如以下代码所示。
import numpy as np import pandas as pd def ZscoreNormalization(x): x = (x - np.mean(x)) / np.std(x) return x Z_views = pd.DataFrame({ 'height': [1.8, 1.7, 1.9, 1.75, 1.68, 1.67], 'weight': [80, 70, 98, 67, 68, 50] }) Z_views['zscore_h'] = ZscoreNormalization(Z_views[['height']]) Z_views['zscore_w'] = ZscoreNormalization(Z_views[['weight']]) print(Z_views)
结果如下:
height weight zscore_h zscore_w 0 1.80 80 0.621770 0.538666 1 1.70 70 -0.621770 -0.148993 2 1.90 98 1.865310 1.776453 3 1.75 67 0.000000 -0.355291 4 1.68 68 -0.870478 -0.286525 5 1.67 50 -0.994832 -1.524311
python中还提供了一个很好用的库sklearn, sklearn是一个基于python的机器学习工具,在这个库中提供了许多简单高效的函数可以作为数据分析的工具,其中StandardScaler()函数就提供了标准化的方法,该函数下的fit_transform能够通过拟合数据的方法得到更好的标准化结果,如以下代码所示。
from sklearn.preprocessing import StandardScaler import pandas as pd views = pd.DataFrame({ 'height': [1.8, 1.7, 1.9, 1.75, 1.68, 1.67], 'weight': [80, 70, 98, 67, 68, 50] }) ss = StandardScaler() views['zscore_h'] = ss.fit_transform(views[['height']]) views['zscore_w'] = ss.fit_transform(views[['weight']]) print(views)
结果如下:
height weight zscore_h zscore_w 0 1.80 80 0.621770 0.538666 1 1.70 70 -0.621770 -0.148993 2 1.90 98 1.865310 1.776453 3 1.75 67 0.000000 -0.355291 4 1.68 68 -0.870478 -0.286525 5 1.67 50 -0.994832 -1.524311
数据归一化(Min-Max标准化)
和数据标准化一样,不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行对数据的处理,但是通过上一小节中的结果可以看到,有一些数据经过标准化后出现了负值的情况,而有些时候负数会影响用户的数据质量,本章讲述不会产生负数的标准化方法。
数据归一化会将所有的数据约束到[0,1]的范围内。
数据归一化公式如下:
公式中min(x)表示数据中的最小值,max(x)表示数据中的最大值。
使用numpy和pandas来实现标准化,如以下代码所示。
import numpy as np import pandas as pd def MaxMinNormalization(x): x = (x - np.min(x)) / (np.max(x) - np.min(x)) return x M_views = pd.DataFrame({ 'height': [1.8, 1.7, 1.9, 1.75, 1.68, 1.67], 'weight': [80, 70, 98, 67, 68, 50] }) M_views['zscore_h'] = MaxMinNormalization(views[['height']]) M_views['zscore_w'] = MaxMinNormalization(views[['weight']]) print(M_views)
结果如下:
height weight zscore_h zscore_w 0 1.80 80 0.565217 0.625000 1 1.70 70 0.130435 0.416667 2 1.90 98 1.000000 1.000000 3 1.75 67 0.347826 0.354167 4 1.68 68 0.043478 0.375000 5 1.67 50 0.000000 0.000000
同样在sklearn中也提供了数据归一化的函数MinMaxScaler(),如以下代码所示。
from sklearn.preprocessing import MinMaxScaler import pandas as pd views = pd.DataFrame({ 'height': [1.8, 1.7, 1.9, 1.75, 1.68, 1.67], 'weight': [80, 70, 98, 67, 68, 50] }) mms = MinMaxScaler() views['minmax_h'] = mms.fit_transform(views[['height']]) views['minmax_w'] = mms.fit_transform(views[['weight']]) print(views)
结果如下:
height weight minmax_h minmax_w 0 1.80 80 0.565217 0.625000 1 1.70 70 0.130435 0.416667 2 1.90 98 1.000000 1.000000 3 1.75 67 0.347826 0.354167 4 1.68 68 0.043478 0.375000 5 1.67 50 0.000000 0.000000
高级数据预处理方法
在数据预处理的过程中还存在着许多高级的预处理方法, 本章详解两种高级的数据预处理方法,哑变量( Dummy Variables)和独热编码(One-Hot Encoding)。
在掌握两种方法之前,需先了解词语向量化(词向量),词向量就是提供了一种数学化的方法,把自然语言这种符号信息转化为向量形式的数字信息。
哑变量( Dummy Variables)
通常将不能定量处理的变量量化,构造只取“0”或“1”的人工变量,通常称哑变量。
示例1: 现在有性别:{男,女,其他}。性别特征有三个不同的分类值,需要三个bit的值来表示这些类别。
独热码表示为:
男:{01},女:{10},其他:{00}。
多个特征时表示为:
性别:{男,女,其他}; 性别编码为:男:{01},女:{10},其他:{00}。
年级:{一年级,二年级,三年级}; 年级编码为:一年级:{10},二年级:{01},三年级:{00}。
对于二年级的男生就可以编码为:{0110}(前面的01表示一年级,后面的10表示男生)。
pandas中提供了get_dummies()函数来实现哑变量,但是需要注意的是该函数生成的数据中不包含全0项,如以下代码所示。
import pandas as pd df = pd.DataFrame({ '性别': ['男', '女', '其他'], '年级': ['一年级', '二年级', '三年级'] }) df = pd.get_dummies(df) print(df)
结果如下:
性别_其他 性别_女 性别_男 年级_一年级 年级_三年级 年级_二年级 0 0 0 1 1 0 0 1 0 1 0 0 0 1 2 1 0 0 0 1 0
结果和原理不同,为什么给出一个具有全0项的定义方法,下一章独热编码会详细解释其原理。
独热编码(One-Hot Encoding)
独热编码是表示一项属性的特征向量,向量中只有一个特征是不为0的,其他的特征都为0(简单的来说就是将一个bit的位置填1,其他位置都填0),比如数据挖掘中对于离散型的分类数据,需要对其进行数字化,使用独热码来表示: 性别:{男,女,其他}。
可以看到上面的性别特征有三个不同的分类值,也就意味着需要三个bit的值来表示这些类别。
独热码表示:
男:{001},女:{010},其他:{100}
多个特征时表示:
性别:{男,女,其他};性别编码为:男:{001},女:{010},其他:{100}
年级:{一年级,二年级,三年级};年级编码为:一年级:{100},二年级:{001},三年级:{010}
对于二年级的男生编码可以为:{001001}(前面的001表示二年级,后面的001表示男生)
能够发现上一章通过get_dummies()函数得到的结果其实是独热编码的结果,可以说二者在实际原理上是有一定偏差的但是在代码的结果显示上却是一致的。关于python中标准的独热编码如以下代码所示。
import pandas as pd from sklearn import preprocessing df = pd.DataFrame({'性别': ['男', '女', '其他'], '年级': ['一年级', '二年级', '三年级']}) ont_hot = preprocessing.OneHotEncoder(categories='auto') df1 = ont_hot.fit(df) # 拟合 print("一年级男生的编码为:{}".format(ont_hot.transform([['男', '一年级']]).toarray())) print("二年级女生的编码为:{}".format(ont_hot.transform([['女', '二年级']]).toarray())) print("三年级男生的编码为:{}".format(ont_hot.transform([['男', '三年级']]).toarray()))
结果如下:
一年级男生的编码为:[[0. 0. 1. 1. 0. 0.]] 二年级女生的编码为:[[0. 1. 0. 0. 0. 1.]] 三年级男生的编码为:[[0. 0. 1. 0. 1. 0.]]
在独热编码中又一次使用了sklearn库,其中的preprocessing模块中提供了很完美OneHotEncode()函数的使用,优点在于能够对数据进行拟合的操作,拟合好了一个模型之后,输入想要的词条的时候,使用transform()函数就能自动的生成需要的编码形式。