以下学习内容参考整理自特征工程, 获得该文的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