[原创]Python-DataMining 数据预处理


以下学习内容参考整理自特征工程, 获得该文的Github地址

将数据转化为DataFrame

  • e.g.1
import pandas as pd

df = pd.DataFrame(np.arange(1, 13).reshape(3, 4), 
                  columns=['A', 'B', 'C', 'D'])
  • e.g.2
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', 'price', 'classlabel']

e.g.2输出的结果:

   color size  price classlabel
0  green   XL   10.1     class1
1    red    L   13.5     class2
2   blue    M   15.3     class1

缺失值处理

  • 删除具有缺失值的一行或一列
  • 用平均值等填充缺失值

原始特征及类别处理

特征项可分为两类:

  • ordinary feature(有序特征):特征项的数值具有大小关系,如尺码大小;
  • nominal feature(无序特征):特征项不具备大小关系,如颜色种类;

各类处理方式如下:
ordinary feature & class_labels:

  • Mapping ordinal features(映射)
# define the mapping manually
size_mapping = {
           'XL': 3,
           'L': 2,
           'M': 1}

df['size'] = df['size'].map(size_mapping)

然后print df得到如下:

   color  size  price classlabel
0  green     3   10.1     class1
1    red     2   13.5     class2
2   blue     1   15.3     class1

还可以转换回去:

# transform the integer values back to the original string
inv_size_mapping = {v: k for k, v in size_mapping.items()}
df['size'].map(inv_size_mapping)

ordinary feature:
对应 nominal(无序) 的 class labels, 也需要将其转换为数值表征,记住此时的数值只代表一个类别,并不表征数值关系

import numpy as np
# 生产类别印射
class_mapping = {label:idx for idx,label in 
                 enumerate(np.unique(df['classlabel']))}

print后得到class_mapping如下:

{'class2': 1, 'class1': 0}

然后开始映射转化

# 最终把 classlabel 也转化为 interger
df['classlabel'] = df['classlabel'].map(class_mapping)

同样,还可以转化回来

# 转化回来也是 ok 的
inv_class_mapping = {v: k for k, v in class_mapping.items()}
df['classlabel'] = df['classlabel'].map(inv_class_mapping)

除了以上方法外,还可以使用LabelEncoder

# sklearn 中也有相应函数
from sklearn.preprocessing import LabelEncoder

class_le = LabelEncoder()
y = class_le.fit_transform(df['classlabel'].values)

输出y得到

array([0, 1, 0])

同样,也可以反向转换

class_le.inverse_transform(y)

nominal feature:

  • get_dummies 函数
import pandas as pd

# pandas 中的 get_dummies 函数是生成 dummy variable 更简单的方法
df = pd.get_dummies(df[['price', 'color', 'size']])

# df[['price', 'color', 'size']] 指明了是对df中'price', 'color', 'size'这几列的内容进行处理;

# pd.get_dummies()在处理时,会将特征项内容为string的作为要转换的特征项,特征项为int或float的不做处理

# 运行时要df = pd.get_dummies(df),这样返回的才是处理后的df

如上df = pd.get_dummies(df[['price', 'color', 'size']])后输出的df:

   size  price  color_blue  color_green  color_red
0     3   10.1           0            1          0
1     2   13.5           0            0          1
2     1   15.3           1            0          0
  • one-hot encoding on nominal features
    首先将特征项内容转化为数字:
X = df[['color', 'size', 'price']].values

# color column
color_le = LabelEncoder()
X[:, 0] = color_le.fit_transform(X[:, 0])

#blue 0
#green 1
#red 2

如上操作后输出的X是:

array([[1, 1, 10.1],
       [2, 2, 13.5],
       [0, 3, 15.3]], dtype=object)

虽然 color 转化为了 0, 1, 2, 但并不能直接使用来建模, 因为在实际使用中, 会认为 2 大于 1, 也就是 red 大于 green. 实际却不是这样的, 所以需要用到 one-hot encoding, 需要使用 dummy variable, 每一个 label 最后被表示为一个向量. 例如, blue sample can be encoded as blue=1, green=0, red=0
处理如下:

from sklearn.preprocessing import OneHotEncoder

ohe = OneHotEncoder(categorical_features=[0], sparse=False)
# 不设定 sparse=False 的话,onehot 会返回一个 sparse matrix, 可以用 toarray() 将之变回 dense

ohe.fit_transform(X)
# 前三列为dummy

输出为:

array([[  0. ,   1. ,   0. ,   1. ,  10.1],
       [  0. ,   0. ,   1. ,   2. ,  13.5],
       [  1. ,   0. ,   0. ,   3. ,  15.3]])

DataFrame写csv文件

dataframe可以使用to_csv方法方便地导出到csv文件中,如果数据中含有中文,一般encoding指定为”utf-8″,否则导出时程序会因为不能识别相应的字符串而抛出异常,index指定为False表示不用导出dataframe的index数据。

df.to_csv(file_path, encoding='utf-8', index=False)

df.to_csv(file_path, index=False)

2017.08.27

你可能感兴趣的:([原创]Python-DataMining 数据预处理)