数据的标准化

数据标准化就是将不同取值范围的数据,在保留各自数据相对大小顺序不变的情况下,整体映射到一个固定的区间中。根据具体的实现方法不同,有的时候会映射到 [ 0 ,1 ],有时映射到 0 附近的一个较小区间内。

这样做的目的是消除数据不同取值范围带来的干扰。


数据标准化的方法,我在这里介绍两种

  • min-max标准化

min-man 标准化会把结果映射到 0 与 1 之间,下面是映射的公式。

    min 是整个样本的最小值,max是整个样本的最大值

  • Z-score标准化

    Z-score会把结果映射到 0 附近,并服从标准正态分布(平均值为 0,标准差为1),下面是映射的公式

    μ 是样本的平均值,σ 是样本的标准差,这些在python中都有函数支持,不用担心计算的问题。


数据的哑编码

哑编码是处理离散型数据的手段。离散型数据的取值范围是有限的(严格在数学上的定义中,无限但可数也就是 countably infinite 的取值空间也属于离散型,但在实际问题中不会碰到,这里不作考虑),比如说星期几就是一个离散型数据,因为一周只有七天,也就只有七种可能的取值。在处理这样的数据的时候,哑编码会把一列数据转换成多列,有多少中可能的取值就转换成多少列。在刚刚提到的星期几的例子中,哑编码会把这一列数据转换成七列数据。

那具体是如何转换的呢?

还是从星期几的例子开始讲

编号 星期几
0 星期二
1 星期一
2 星期五
3 星期日
4 星期三
5 星期六
6 星期四
7 星期日
8 星期二
9 星期四

假设我们有这样的十条数据,现在数据除了编号以外只有一个字段——“星期几”。

哑编码会讲这一个字段扩展成七个字段,也就是七列,每一个新的字段代表原来字段的一种取值,现在表格变成了

编号 星期几 星期一 星期二 星期三 星期四 星期五 星期六 星期日
0 星期二              
1 星期一              
2 星期五              
3 星期日              
4 星期三              
5 星期六              
6 星期四              
7 星期日              
8 星期二              
9 星期四              

那如何表示原来的数据呢?很简单,如果编号0的数据是星期一,那么在星期一这个字段上的数值是1,在其他所有字段上都是0,现在数据变成了这样

编号 星期一 星期二 星期三 星期四 星期五 星期六 星期日
0 0 0  0 0  0 0
1  0 0  0 0  0 0
2 0  0 0 0  0 0
3 0  0 0 0 0  0
4 0  0  0 0  0 0
5 0  0 0  0 0 0
6 0  0 0   0  0 0
7 0 0 0  0 0  0
8 0  1 0  0 0  0 0
9 0  0 0   0  0 0

最后再删去原来的字段,大功告成!


pandas

我们一会儿会用python里的pandas来处理数据,所以这里先简单介绍一下我们一会儿会用到的知识。

  • dataframe

    简单的理解,dataframe就是一张二维表,和上面例子中关于星期几的表格完全一样。

    我们可以通过行号和列明的方式定位表中的某一个元素,dataframe也是这样。

    假设我们有一个变量叫df,它是一个dataframe

df[0] # 访问第0行元素
df['column_name'] # 访问列名为 column_name 的一列数据
df.loc[0,'column_name'] # 访问第0行列名为 column_name 的元素
  • dtype

    dtype是 dataframe中每一列的数据类型,常用的有 float32 float64 int32 int16 等等

    可以通过 dtypes 或 dtype 访问数据类型

df.dtypes # 所有列的数据类型
df['column_name'].dtype # 列名为 column_name 的数据类型

    数据类型可以通过 astype 函数更改

df["column_name"] = df["column_name"].astype(np.int16) # 讲列名为 column_name 的列的数据类型改为 np.int16

数据标准化的代码实现

下面就是代码实现部分了,我会把我写整个代码的思路一点点的剖析开

首先当然是将要用到的包导入了

import pandas as pd
import numpy as np

上面提到了两种实现方式,但为了便于使用,我不想写两个函数,我希望只暴露给用户一个函数,将这两种实现方法融合在一起。

具体来说,就是用一个参数来确定用户本次调用的到底是哪种实现方式,并可以通过给出参数默认值的方式给出默认实现方式。

def normalize(data, columns, function='min-max'):
if function == 'min-max':
return min_max_scalar(data, columns)
elif function == 'standard':
return standard_scalar(data, columns)
else:
raise ValueError("invalid parameter: function must be 'min-max' or 'standard'.") def min_max_scalar(data, columns):
pass def standard_scalar(data, columns):
pass
  • data : 代表需要处理的数据表格,类型是 dataframe
  • columns :代表需要处理的列的列明的集合,类型是 list,其中每个元素应该是字符串或是可以转换成字符串
  • function :具体指定实现方式,默认为 min-max 标准化

整体的思路就是判断一下function的数值,然后调用相应的函数

现在整个函数的框架搭起来了,接下来的就是具体实现 min_max_scalar(data, columns)standard_scalar(data, columns) 两个函数了

先来实现 min_max_scalar(data, columns)

def min_max_scalar(data, columns):
for column in columns:
maxi = max(data[column])
mini = min(data[column])
if maxi == mini:
raise ValueError("invalid parameter value: maximum element equals to minimum element in the '" + column + "' column.")
else:
diff = maxi - mini
data[column] = ( data[column] - mini ) / diff
return data

很简单吧?不过一定要随时记得处理异常,在这种实现方式中,如果数据的最大值最小值相同,就会造成 ZeroDivisionError 这个异常,所以我们单独判断,处理了一下这种情况。

然后我们实现 standard_scalar(data, columns)

def standard_scalar(data, columns):
for column in columns:
std = np.std(data[column])
if std == 0:
raise ValueError("invalid parameter: standard deviation is 0 in the '" + column + "' column.")
else:
mean = sum(data[column]) / len(data[column])
data[column] = ( data[column] - mean ) / std
return data

这里处理了一下标准差为零的异常情况

图省事的同学就可以往下看哑编码部分的代码了,不过,如果你想让你的函数更加 robust,我们还得加入大量的异常处理代码

我们需要做哪些异常处理?

  • 判断 data 的数据类型是否是 dataframe?
  • columns 的数据类型是否是list,或者是否能转换成list?
  • columns 中每个元素是不是字符串,或者是否能转换成字符串?
  • columns 中每个元素代表的列是否真的存在?
  • 如果存在,这个列的数据是数值类型的数据么?
  • function 是一个字符串么?
  • 如果是,那这个字符串是否是 ‘min-max’ 或 ‘standard’ 二者之一么?

直接看代码吧

def normalize(data, columns, function='min-max'):
if type(data) != pd.core.frame.DataFrame:
raise TypeError("invalid parameter: data must be a dataframe.") try:
columns = list(columns)
except TypeError:
raise TypeError("invalid parameter: columns must be a list or can be converted to a list.") try:
for counter in range(len(columns)):
columns[counter] = str(columns[counter])
except TypeError:
raise TypeError("invalid parameter: each column element in columns should be a string or can be converted to a string.") for column in columns:
if column not in data.columns:
raise ValueError("invalid parameter: column '" + column + "' doesn't exist.") is_int = data[column].dtype == np.int8 or data[column].dtype == np.int16 or data[column].dtype == np.int32 or data[column].dtype == np.int64
is_uint = data[column].dtype == np.uint8 or data[column].dtype == np.uint16 or data[column].dtype == np.uint32 or data[column].dtype == np.uint64
is_float = data[column].dtype == np.float16 or data[column].dtype == np.float32 or data[column].dtype == np.float64
if is_int or is_uint or is_float:
data[column] = data[column].astype(np.float64)
else:
raise TypeError("invalid parameter: values in column '" + column + "' should be numbers ") try:
function = str(function)
except TypeError:
raise TypeError("invalid parameter: function must be a string or can be converted to a string.") if function == 'min-max':
return min_max_scalar(data, columns)
elif function == 'standard':
return standard_scalar(data, columns)
else:
raise ValueError("invalid parameter: function must be 'min-max' or 'standard'.")

是不是懵逼了?这异常处理代码写出来比主程序还长 orz~


数据哑编码的代码实现

还是先把大致的框架搭起来

def one_hot_encoder(data, columns):
# 异常处理
pass
# 处理数据

data 和 columns 的含义与上文相同,不再赘述。

这次我们先来处理异常,我们需要考虑

  • 判断 data 的数据类型是否是 dataframe?
  • columns 的数据类型是否是list,或者是否能转换成list?
  • columns 中每个元素是不是字符串,或者是否能转换成字符串?
  • columns 中有没有重复的元素?
  • columns 中每个元素代表的列是否真的存在?
  • columns 中每个元素代表的列的数据是否是字符串,或者是否能转换成字符串?

下面看代码~

def one_hot_encoder(data, columns):
# 异常处理
if type(data) != pd.core.frame.DataFrame:
raise TypeError("invalid parameter: data must be a dataframe.") try:
columns = list(columns)
except TypeError:
raise TypeError("invalid parameter: columns must be a list or can be converted to a list.") try:
for counter in range(len(columns)):
columns[counter] = str(columns[counter])
except TypeError:
raise TypeError("invalid parameter: each element in columns should be a string or can be converted to a string.")
columns = np.unique(columns) # rule out duplicate column name to avoid error for column in columns:
if column not in data.columns:
raise ValueError("invalid parameter: column '" + column + "' doesn't exist.")
try:
data[column] =data[column].astype(str)
except Exception:
raise TypeError("invalid parameter: value in '" + column + "' must be a string or can be converted to a string.") # 处理数据
return help_encoder(data, columns)

我把处理数据的部分写到  help_encoder(data, columns) 函数中了,这里只做调用

接下来就剩下下最后一步,处理数据了,相比于数据标准化,这块的代码稍微复杂一点,需要细心点看。

def help_encoder(data, columns):
for column in columns:
unique_values = np.unique(data[column])
sub_column_names = []
for unique_value in unique_values:
sub_column_names.append(column + '_' + unique_value)
# insert new columns
for sub_column_counter in range(len(sub_column_names)):
data[sub_column_names[sub_column_counter]] = -1
for data_counter in range(len(data)):
data.loc[data_counter, sub_column_names[sub_column_counter]] = int(data[column][data_counter] == unique_values[sub_column_counter])
# remove old columns
del data[column] return data

最后我们测试一下哑编码部分的代码

data = pd.DataFrame([['A'], ['B'], ['C'], ['D'], ['A'], ['E']] ,columns=list('A')) # 创建 dataframe
print('哑编码之前')
print(data)
one_hot_encoder(data, ['A']) #进行哑编码处理
print('哑编码之后')
print(data)

运行结果

哑编码之前
A
0 A
1 B
2 C
3 D
4 A
5 E
哑编码之后
A_A A_B A_C A_D A_E
0 1 0 0 0 0
1 0 1 0 0 0
2 0 0 1 0 0
3 0 0 0 1 0
4 1 0 0 0 0
5 0 0 0 0 1
[Finished in 1.5s]

大功告成!

利用 pandas 进行数据的预处理——离散数据哑编码、连续数据标准化的更多相关文章

  1. Python利用pandas处理Excel数据的应用

    Python利用pandas处理Excel数据的应用   最近迷上了高效处理数据的pandas,其实这个是用来做数据分析的,如果你是做大数据分析和测试的,那么这个是非常的有用的!!但是其实我们平时在做 ...

  2. 利用pandas库中的read_html方法快速抓取网页中常见的表格型数据

    本文转载自:https://www.makcyun.top/web_scraping_withpython2.html 需要学习的地方: (1)read_html的用法 作用:快速获取在html中页面 ...

  3. (数据科学学习手札63)利用pandas读写HDF5文件

    一.简介 HDF5(Hierarchical Data Formal)是用于存储大规模数值数据的较为理想的存储格式,文件后缀名为h5,存储读取速度非常快,且可在文件内部按照明确的层次存储数据,同一个H ...

  4. 浅谈python之利用pandas和openpyxl读取excel数据

    在自学到接口自动化测试时, 发现要从excel中读取测试用例的数据, 假如我的数据是这样的: 最好是每行数据对应着一条测试用例, 为方便取值, 我选择使用pandas库, 先安装 pip instal ...

  5. 利用 pandas库读取excel表格数据

    利用 pandas库读取excel表格数据 初入IT行业,愿与大家一起学习,共同进步,有问题请指出!! 还在为数据读取而头疼呢,请看下方简洁介绍: 数据来源为国家统计局网站下载: 具体方法 代码: i ...

  6. python-数据描述与分析2(利用Pandas处理数据 缺失值的处理 数据库的使用)

    2.利用Pandas处理数据2.1 汇总计算当我们知道如何加载数据后,接下来就是如何处理数据,虽然之前的赋值计算也是一种计算,但是如果Pandas的作用就停留在此,那我们也许只是看到了它的冰山一角,它 ...

  7. Amazon评论数据的预处理代码(Positive & Negative)

    Amazon评论数据的预处理代码,用于情感分析,代码改自 https://github.com/PaddlePaddle/Paddle/tree/develop/demo/quick_start/da ...

  8. 利用pandas读取Excel表格,用matplotlib.pyplot绘制直方图、折线图、饼图

    利用pandas读取Excel表格,用matplotlib.pyplot绘制直方图.折线图.饼图 数据: 折线图代码: import  pandas  as pdimport  matplotlib. ...

  9. pandas 学习 第14篇:索引和选择数据

    数据框和序列结构中都有轴标签,轴标签的信息存储在Index对象中,轴标签的最重要的作用是: 唯一标识数据,用于定位数据 用于数据对齐 获取和设置数据集的子集. 本文重点关注如何对序列(Series)和 ...

随机推荐

  1. 【京东详情页】——原生js爬坑之二级菜单

    一.引言 做京东详情页仿写的时候,要用原生js实现顶部菜单的二级菜单显示与隐藏事件的触发. 过程中遇到了一个坑,在这里与大家分享.要实现的效果如下: 二.坑 谁触发事件?显示.隐藏二级菜单       ...

  2. Go语言备忘录:基本数据结构

    本文内容是本人对Go语言的变量.常量.数组.切片.映射.结构体的备忘录,记录了关键的相关知识点,以供翻查. 文中如有错误的地方请大家指出,以免误导!转摘本文也请注明出处,多谢! 参考书籍<Go语 ...

  3. 强大的桌面用 PDF 重排工具:K2pdfopt 简明教程

    用 Kindle 阅读 PDF 一直以来都遭到小伙伴们的无限吐槽,在那 Kindle 还能越狱的时代,我们有 Koreader 之类优秀的 Kindle 第三方插件实现 PDF 文档的实时重排,但是随 ...

  4. css控制div强制换行

    div{white-space:nowrap;} 自动换行 div{ word-wrap: break-word; word-break: normal; } 强制英文单词断行 div{word-br ...

  5. Delphi中 StrToIntDef函数的用法

    Delphi中 StrToIntDef函数的用法:比如我要判断一个文本框里输入的字符串能不能转换为integer类型,如果能,则返回转换后的整型数据,如果不能,则返回整数0,那么我就可以用strtoi ...

  6. “==”与"equals(object)"的区别

    一.对于基本数据类型而言只能用“==”,不能用equals来进行比较,若使用equals来进行比较,则不能通过编译 二.在非字符串的对象的比较中: “==”与“equals()”比较的均是对象在堆内存 ...

  7. 1007 正整数分组 1010 只包含因子2 3 5的数 1014 X^2 Mod P 1024 矩阵中不重复的元素 1031 骨牌覆盖

    1007 正整数分组 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组,3 5分为1组,两组和相差1,是所有方案中相差最少的.   Input 第1行:一个 ...

  8. Django的form表单之文件上传

    在生成input标签的时候可以指定input标签的类型为file类型 <!DOCTYPE html> <html lang="en"> <head&g ...

  9. FastDFS的安装步骤

    1.安装相关环境 yum install -y gcc-c++ yum -y install libevent yum install -y pcre pcre-devel yum install - ...

  10. java中属性,set get 以及如何学习类的一些用法

    1,先来看一个例子 package com.tdq.java; public class Run { public static void main(String[]args){ Student st ...