用pandas进行简单的数据预处理

最在参加了一个机器学习的竞赛,又开始频繁的使用pandas做数据的处理。发现了一些之前没有发现的pandas用法。在这里做一个总结, 也算是学习笔记吧。本笔记大部分都会以下面的数据作为例子。另外,推荐大家使用ipython来查看及处理数据。

首先看这样的数据。

image.png

这是kaggle上的关于员工离职的数据,现在要根据满意度,工作项目, 薪水等指标判断一个员工是否会离职。 在进行机器学习之前,我们首先要进行数据的清理及预处理。数据下载

1. 查看统计数据

csv文件读取

拿到数据以后,一般都要先看看数据长啥样,有多大,都有什么特征,用pandas查看这些是非常方便的。针对本例子中的csv文件, 我们使用read_csv函数来读取, 读进来之后是pandas中的DataFrame格式。

import numpy as np
import pandas as pd
# 使用read_csv读取数据
hr = pd.read_csv("HR.csv")

但有一点要注意,读取的时候要先看一下csv文件中格式。主要看两点,一是第一列(也有可能是前几列)是不是索引,二是看第一行是数据还是feature的名称。 read_csv方法默认会将第一行当成feature来解析。

# 如果第一列是索引
pd.read_csv('data.csv', index_col=0)
# 如果是纯数据没有feature的话
pd.read_csv('data.csv', header=None)

实际上如果你用的是ipython,可以直接输入 pd.read_csv? 来查看这个函数的文档,非常方便。

查看数据
# 查看数据的行数与列书, 一般来说行代表样本数, 列代表feature数
hr.shape
# 查看数据的前5行
hr.head()
# 查看每一列的计数及数据类型等信息
hr.info()
# 查看统计信息
hr.describe()

一般来说我们都会看一下这些信息。 从而对数据有一定的概念。

2. 简单的可视化

   pandas提供了一个简单的函数让我们可以非常简单的查看各个column的分布直方图,当然仅限于该column的值的数字的时候,如果是离散值就没有用这个办法可视化了。值得注意的是该函数依赖于matplotlib, 须先导入该包。
import matplotlib.pyplot as plt
hr.hist(grid=False, figsize=(12,12))

有两个参数值得一提

grid : True 或者 False; 就是设不设置网格, 这个就看个人的需求了
figsize: tuple;图的大小, 当你绘制的直方图有多个时, 就设置大一点,这个多尝试几次就好了

至于其他的参数,一般来说用的不多, 但如果有需求可以看一下文档,强烈建议用ipython,这用就可以直接用 hr.hist? 来查看该函数的文档了。

3. 去除重复项

pandas提供了duplicated 函数供我们查看是否有完全一样的两行,也就是重复的两行,返回的是一个Boolean值的Series,重复项那里就是True,无重复项的False

# 可以通过df.duplicated()查看是否有重复项
hr.duplicated(keep="last")

keep: "first", "last", False. 默认是"first". 非常重要的参数,first的意思就是重复项里面第一个为False, 剩下的事True, last的意思则正好相反,最后一项是False, 其他重复项为True。指定为False则表示把所有重复项都设置为True
subset: list, 要检查重复的项,默认是全部,也就是两行完全一样才判断为True。 如果只是像查看部分column是否一样的话就可以用subset这个参数了。

除了查看重复的项,我们还可以去除重复项。drop_duplicates提供了这一功能。

hr = hr.drop_duplicates()

keep: "first", "last", False. 默认是“first”。 也就是默认保留最前面的重复项,将其他重复项去除。“last”则表示保留最后面的重复项,将其他重复项去除。False则表示将所有重复项全部去除。
subset: list, 默认是全部列。如果只是要将其中几列相同就去除的话可以用这个参数。
inplace: True or False。 默认是False,也就是不修改原来的DataFrame。设置为True则会改变原来的DataFrame。

4. 处理缺失值

缺失值的处理一直是数据处理的一个重点工作。根据数据的不同会做出不同的选择,有用均值填充的,中位数填充的,用0填充的,甚至直接去除的。再复杂一点的可以用autoencoder来训练预测缺失值,关于缺失值的处理可以写一本厚厚的书了。这里就简单的说明一下常见的处理方法。注意我这个数据没有缺失值,大家可以找找其他数据试一下。

# 用均值填充
hr.fillna(hr.mean())
# 用中位数填充
hr.fillna(hr.median())
# 用0填充
hr.fillna(0)

5. 离散的feature处理

包含离散的feature的数据无法直接作为输入进行机器学习。例如性别,男跟女,例如工资,low,medium,high。 需要做一个向量化处理。有人说不能直接用0,1,2来表示吗,例如0表示low,1表示medium, 2表示high。emmmm,当然不行。怎么向量化呢?以该数据中的工作岗位与工资为例, 001 表示low ,010表示medium,100表示表示high。

categorical_features = ['sales', 'salary']
hr_cat = pd.get_dummies(hr[categorical_features])
hr = hr.drop(categorical_features, axis=1)
hr = pd.concat([hr, hr_cat], axis=1)

很简单的代码,值得一提的事get_dummies这个函数。该函数的作用是将离散的变量转化为向量化,一两句说不清,这里只告诉你可以这么处理离散变量,想要细细了解看一下文档就明白了,我把文档贴过来也没有意思。

6. 数据归一化

向量归一化也是非常重要的。最常见的归一化方法有两种,一种是min-max归一化,就是每一个值除以最大值减去最小值的差,这样可以把数据归一化到[0,1]之间。另一种是z-score标准化,也就是经过处理后的数据符合标准正态分布,即均值为0,标准差为1。这两种都非常常见,具体使用哪种得看数据。可以用sklearn来进行处理,这样就不用自己来实现了。

from sklearn.preprocessing import StandardScaler
# 使用z-score标准化数据
ss = StandardScaler()
scale_features = ['number_project', 'average_monthly_hours', 'time_spend_company']
hr[scale_features] = ss.fit_transform(hr[scale_features])

如果是想用min-max归一化的话,sklearn也有现有的类实现。

from sklearn.preprocessing import MinMaxScaler
ss = MinMaxScaler()
scale_features = ['number_project', 'average_monthly_hours', 'time_spend_company']
hr[scale_features] = ss.fit_transform(hr[scale_features])

7. 去除缺失比例超过50%的行/列

这是我在处理其他数据的时候遇到的问题, 就是有时候并不只是单纯的根据一部分column来去除数据,而是要根据缺失比例来进行取舍。有可能是缺失比例超过30%,或者70%。我查了一下pandas好像没有现有的函数直接实现的。但不打紧,我写了两个函数来实现。

  • 去除缺失值比例超过一定程度的列
def drop_col(df, cutoff=0.4):
    n = len(df)
    for column in df.columns:
        cnt = df[column].count()
        if (float(cnt) / n) < cutoff:
            df = df.drop(column, axis=1)
    return df
hr = drop_col(hr)

当然本文中数据是没有缺失值的,因此没有什么效果。注意cutoff指的是有数据的比例。

  • 去除缺失值超过一定比例的行
def drop_row(df, cutoff=0.8):
    n = df.shape[1]
    for row in df.index:
        cnt = df.loc[row].count()
        if cnt / n < cutoff:
            df = df.drop(row, axis=0)
    return df
hr  = drop_row(hr)

同样的,这里的cutoff也是只有数据的比例

8. 根据条件给列数据重新赋值

这个应该也是非常常见的功能。举个简单的例子,现在要把Work_accident中大于2的值改为True,小于等于2的值改为False。例子要求可能不太合理,但意思应该表达出来了。这种要求怎么实现呢。非常简单,一句就可以搞定了。

hr['Work_accident'] = hr['Work_accident'].apply(lambda x: False if x<2 else True)

如果要求比较复杂,就不要用匿名函数了,自己写一个函数,然后像上面那样子就成了。非常简单的。

大致应该讲完了常见的数据预处理,如果再工作中遇到新的需求,我会不定期的更新本文

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容