了解数据

数据收集及读取

数据收集

  • 数据接口 -- 一些网站有API接口,通过相应的API请求方式就能获取到想要的数据,一般情况下数据会非常规范,完整。
  • 数据库 -- 需要得到授权。
  • 数据爬虫 -- 优势在于你无需数据拥有者提供权限,缺点是获取到的数据特征有限,往往会有更多丢失或错误数据。

数据读取
1.数据文件读取
数据文件,最常见到的有.csv, .txt,少见有.xlsx格式的文件。对于存在本地的.csv, .txt数据文件,首先用open()方法:

file = open("xxx.csv", 'r')
for line in file:
    print(line)

对于excel支持的.xlsx文件需要安装xlrd包:

sudo pip3 install xlrd
import xlrd

file = xlrd.open_workbook("xxx.xlsx")
# 按索引读取表
table = file.sheet_by_index(0)
# 读取每行并打印
for i in range(table.nrows):
    print(table.row_values(i))

open方法的局限很多。所以大多数情况下都会数据预处理神器Pandas来完成数据文件的读取工作。

import pandas as pd


df = pd.read_csv("xxx.csv")
print(df)

使用Pandas读取文件方便,代码简洁,读取的数据直接就是DataFrame。
除了csv文件,Pandas还可以读取其他文件:

# JSON文件
pd.read_json

# HTML文件
pd.read_html

# 本地剪切板
pd.read_clipboard

# MS Excel文件
pd.read_excel

# HDF5Format文件
pd.read_hdf

# Feather 格式
pd.read_feather

# Msgpack
pd.read_msgpack

# Stata
pd.read_stata

# SAS
pd.read_sas

# Python Pickle格式
pd.read_pickle

# SQL数据库
pd.read_sql

# Google Big Query
pd.read_gbq
 

对于Pandas读取数据方法,还带有很多参数。比如txt格式的文件:

df = pd.read_table("xxx.txt", header=0, sep='\t')
print(df)

这里,header=0表示将第一行设为表头,而sep='\t'则代表使用空格分隔字段。

2.数据库读取
除了数据文件,如果想要读取 MySQL,Oracle,Microsoft SQL 等数据库里面的数据。一般情况下都需要安装相应的第三方库。例如,读取 MySQL 时,我们需要安装 MySQLdb:

sudo apt-get install python-dev libmysqlclient-dev
sudo pip install MySQL-python

安装之后启动mysql服务:

sudo service mysql start

然后使用root用户登陆:

mysql -u root -p

向数据库写入一些数据:

# 创建名为xxx的数据库
mysql> CREATE DATABASE xxx;
Query OK, 1 row affected (0.01 sec)

# 切换到该库
mysql> use xxx
Database changed

# 创建名为person的表
mysql> CREATE TABLE person (id int(10),name char(20),phone int(12));
Query OK, 0 rows affected (0.06 sec)

# 写入示例数据1
mysql> INSERT INTO person VALUES(01,'Tom',110110110);
Query OK, 1 row affected (0.02 sec)

# 写入示例数据2
mysql> INSERT INTO person VALUES(02,'Jack',119119119);
Query OK, 1 row affected (0.02 sec)

# 写入示例数据3
mysql> INSERT INTO person VALUES(03,'Rose',112222119);
Query OK, 1 row affected (0.01 sec)

通过MySQLdb连接并读取数据。

>>> import MySQLdb

# 连接数据库
>>> db = MySQLdb.connect(host="localhost", user="root", passwd="", db="xxx")

# 获取操作游标 
>>> cur = db.cursor()

# 使用 execute 方法执行 SQL 查询语句
>>> cur.execute("SELECT * FROM person")
3L

# 输出查询
>>> for row in cur.fetchall():
...     print row # 注意缩进
... 
(1L, 'Tom', 110110110L)
(2L, 'Jack', 119119119L)
(3L, 'Rose', 112222119L)

# 关闭数据库连接
>>> db.close()

数据预处理

数据概览

Pandas为我们提供了相应的函数。通过这些函数方法,我们可以很方便的概览数据。

import pandas as pd


df = pd.read_csv("test.csv")

# 浏览头部数据
df.head()

# 浏览尾部数据
df.tail()

# 不带参数的head()和tail()方法默认显示5条数据,
# 也可以自定义显示数据条数
df.head(10)

# describe()方法可以对数据集中的数值进行统计,
# 会输出数据计数,最大值,最小值等
df.describe()

count()方法可以用于计算数据集中非空数据的数量:
df.count()

缺失值处理

缺失值是指数据集中的某一些行或列出现数值丢失。造成这种现象的原因,有可能是数据没有采集成功,或者是因为传输、存储出现故障。

1.查找缺失值

查找缺失值,我们依旧可以使用 Pandas 进行处理。Pandas 中,缺失数据一般采用NaN标记NaN 代表 Not a Number。特别地,在时间序列里,时间戳的丢失采用 NaT 标记。

Pandas 用于检测缺失值主要用到两个方法,分别是:isnull() 和 notnull(),故名思意就是「是缺失值」和「不是缺失值」。默认会返回布尔值用于判断。

import pandas as pd


df = pd.read_csv("test.csv")
print(df.head(10).isnull())
print(df.head(10).notnull())

2.删除缺失值所在的列或行

删除缺失值是最简单直接的办法之一。它适用于三种情况:

  • 缺失值少,对数据集的影响可以忽略不计。这句话的意思应该很好理解。比如一个数万行的数据集,恰好有某几行缺失了几个特征值。缺失的数据行远远小于全部数据的数量,且删除这几行之后,对原数据集的影响可以忽略。这时候,直接删除缺失值所在的行是最好的。

  • 缺失数据量大,已无法挽救。举个例子,一个数据集有1 万行,存在 10 个特征列。其中某一项特征所在的列存在 9000 个空值。这也就表明该列存在的意义已经不大了。所以也需要删除数据。

  • 该缺失值无法被填充。这种情况也很常见。就拿我们上面一直在用的 test_file.csv 数据集距离。该数据集实际为洛杉矶人口普查数据。我们可以看到数据集中有一列为 Zip Code,也就是邮编。邮编是客观存在的,也是不能随意更改的。如果某几项邮编缺失,你是无法随意通过一些数值来填充邮编。所以,对应这样的数据行已经没有意义,选择直接删除往往是最好的。

删除缺失值所在的列或行非常简单,使用Pandas提供的 dropna() 方法。dropna() 方法可以将有缺失值的行或列全部移除。当然,你可以使用 axis=0 参数指定行,或 axis=1 参数指定列:

import pandas as pd


df = pd.read_csv("xxx.csv")
print(df.dropna(axis=0))
print(df.dropna(axis=1))

因为可能每一列都有空值,所以删除列要慎用。

3.填充缺失值

除了删除缺失值,对缺失值处理的另外一种方法就是填充缺失值。如果你第一次接触缺失值处理,你可能会认为填充缺失值的处理好于直接删除缺失值。其实并不一定,原因在于填充缺失值会直接改变原有数据集,这可能会影响后续预测分析的结果。所以,使用填充缺失值时一定要更加谨慎。

一般情况下,填充缺失值有三种方法。

  • 手动填充。手动填充虽然是笨办法,但往往是效果最好的方法。手动填充非常适合于一种情形,那就是数据可以被人为有效确定。举个例子:上面的洛杉矶人口普查数据表中,第一列为邮编,它用于标记不同的地区。如果邮编有几项数据缺失,那么通过手动筛选再填充邮编就是最适合的方法。原因在于,邮编和其他数据不一样,如果它不存在或不正确,就直接导致这行数据无效,甚至影响到其他数据。手动填充,充分展现了人的灵活性,但同样是一个费时费力的办法。

  • 临近填充。 临近填充,故名思意就是采用与缺失值相邻的数据进行填充缺失值的方法。临近填充比较适合于零散的不确定数据。零散,指的是不会连续缺失数十个或上百个数据值。如果连续缺失的值太多,你用临近填充将其变为同一数据值,这对数据集整体的影响可想而知。不确定数据,就是通过视觉观察,无法发现相邻数据之间有什么联系,前后数据时大时小,无法被人为确定或找出规律。

Pandas 提供了用于临近填充的fillna()方法。该方法的使用示例如下:

import pandas as pd


# 被前面的临近值填充
df = pd.read_csv("xxx.csv")
print(df.head(10).fillna(method='pad'))

#被后面的临近值填充
df = pd.read_csv("xxx.csv")
print(df.head(10).fillna(method='bfill'))

fillna()方法在填充时并不会影响原有的数据集。

  • 插值填充。插值填充就是采用数学的方法对数据进行插值。举个例子,有一列数据为 [2011, 2012, 2013, 缺失值, 缺失值, 2016, 2017] 。这里,无论你采用向前还是向后填充,其实都不是最好的。你可以发现数据是一个等差数列,缺失值应该分别为[2014, 2015],这也就是一个线性插值的过程。

Pandas 提供了相关插值方法,通过interpolate()方法实现。默认为参数为线性插值,即 method='linear'。举例:

import pandas as pd


df = pd.read_csv("xxx.csv")
print(df.interpolate().head(10))

除此之外,interpolate()方法还有{‘linear’, ‘time’, ‘index’, ‘values’, ‘nearest’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘barycentric’, ‘krogh’, ‘polynomial’, ‘spline’, ‘piecewise_polynomial’, ‘from_derivatives’, ‘pchip’, ‘akima’}等插值方法可供选择。

  • 如果你的数据增长速率越来越快,可以选择 method='quadratic'二次插值。
  • 如果数据集呈现出累计分布的样子,推荐选择 method='pchip'。
  • 如果需要填补缺省值,以平滑绘图为目标,推荐选择 method='akima'。
  • 另外,method='akima',method='barycentric' 和 method='pchip' 需要 Scipy 才能使用。

独热编码

在对数据的预处理过程中,我们会遇到有一些特征列中的样本并不是连续存在的,而是以分类形式存在的情况。例如,某一装置的状态有三种情况,分别为:正常、机械故障、电路故障。如果我们要将这些数据运用到后续的预测分析中,就需要对文字状态进行转换。一般情况下,可以用 0 表示正常,1 代表机械故障,2 代表电路故障。

但是这种映射方式,往往会让学习器认为 2 代表电路故障比 1 代表机械故障更「大」,从而影响模型分析结果,这肯定是不行的。

所以,对于以分类形式存在的特征变量,我们会采用一种叫独热编码(One-Hot Encoding)的方式将其转换成二元特征编码,进一步对特征进行了稀疏处理。独热编码采用位状态寄存器来对个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。举例如下:


image.png

Pandas提供了更简单的方式来处理以分类形式的变量。可以通过get_dummies()将以分类形式存在的变量转换为独热编码。

import pandas as pd


df = pd.read_csv("one_hot_demo.csv", header=0)
df.head(10)

在此演示文件中,status共有none, electric, engine三类数值。color有red和green两类。


data_1.png
oneHot = pd.get_dummies(df[['status', 'color']])
oneHot.head(10)
data_2.png

字符串被进行了独热编码,特征也从原先的2列拓充为5列。所以,独热编码好处多多。

重复值处理

pandas.Dataframe.duplicated()可以用来标识重复数据,数据集中的重复数据行会返回布尔类型True。
上面的独热编码示例数据中存在大量重复数据,就拿它来举例:

import pandas as pd


df = pd.read_csv("one_hot_demo.csv", header=0)
print(pd.DataFrame.duplicated(df).head(10))
data_3.png

pandas.DataFrame.drop_duplicates()可以返回一个去重后的数据集。

import pandas as pd


df = pd.read_csv("one_hot_demo.csv", header=0)
print(pd.DataFrame.drop_duplicates(df))

去重后的数据集如下,仅有6行非重复项。


data_4.png

异常值检测

一种简单直观的异常值检测方法,那就是通过箱形图(箱线图)来识别异常数据。箱形图是用来观测数据集分布的一种图形类型。箱形图中,从上到下依次有 6 个数据节点,分别是上界、上四分位、均值、中位数、下四分位、下界。而那些超过上界的值就会被标记为离群点,也就是异常数据。

from matplotlib import pyplot as plt
import pandas as pd


data = pd.read_csv("test_file.csv", header=0)
Total_Population = data["Total_Population"]
plt.boxplot(Total_Population)
plt.show()
data_5.png

将离群点标记并导出:

from matplotlib import pyplot as plt
import pandas as pd


data = pd.read_csv("test_file.csv", header=0)
Total_Population = data["Total_Population"]
P = plt.boxplot(Total_Population)
outlier = P['fliers'][0].get_ydata()
print(outlier)

data_6.png

DataFrame带有boxplot()方法可以很方便地将所有列数据的箱形图画在一张图中对比:

from matplotlib import pyplot as plt
import pandas as pd


data = pd.read_csv("test_file.csv", header=0)
data.boxplot()
plt.show()

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

推荐阅读更多精彩内容