一.Pandas基础用法
20210405 fancy_lee
1.pandas介绍
Python Data Analysis Library 或 pandas ,是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的,
pandas是python里面分析结构化数据的工具集,基础是numpy,图像库是matplotlib
提供了大量能使我们快速便捷地处理数据的函数和方法。
2.数据结构
2.1Series
是由一组数据(各种NumPy数据类型),以及一组数据标签(索引)组成,不要求数据类型是相同的。可以看作是一维数组
# 基本操作
import pandas as pd
import numpy as np
# index必须为list
pd.Series(data,index)
# 有点类似于 字典
s1=pd.Series(data=[3,-5,7,4],index=list('abcd'))
# 但可以通过默认索引 和 自定义索引
# 一般用自定义的索引访问
print(s1[0],s1['a'])
# 修改 直接查询后赋值
s1[0]=8
# 比较按条件输出 比较值的大小 输出符合条件的seris
s1[s1>3]
2.2 DataFrame
DataFrame的单列数据为一个Series,第一列为行索引,数据列为列索引
1.创建
# 创建一个DataFrame
date=pd.date_range(start='20100101',end='20100106')
date
# 行索引(第一列) 列索引 填充的数据
df=pd.DataFrame(index=date,columns=list('abcd'),data=np.random.randn(6,4))
# 属性 .values值(ndarray) .index(行索引) .colums .dtypes .size .ndim .shape(数据的行列数,不包括行索引)
2.删除
pandas提供的方法drop
df.drop(labels, axis=0, level=None, inplace=False, errors='raise')
# axis为 0时表示 删除行,axis为1时表示删除列。
# 参数
labels 代表删除行或列的标签 必填
axis x为1 y为0
levels 标签所在的级别 int或索引名
inplace False 不对原数据生效
# 删除a,b列数据
df1=df.drop(labels=['a','b'],axis=1,inplace=False)
# 删除第一行
df2=df.drop(labels=date[0],axis=0)
3.修改
# 添加和修改列 或新元素 默认在末尾添加new列
df['new']=
# 或者先查询出需要修改的列再直接=
# 位置插入
data.insert(2,'c','')
# 2 :插入的列的位置
# ‘c':待插入列的列名
# ‘ ’:插入的值,这里插入的是空值
3.访问
# 列访问 单列
df.a
df['a']
df[['a','b']] # 列访问 多列 返回新的dataframe
# 行访问 连续访问使用':' 特定行访问使用['20100101',20100103']
df[0:1] #访问第0行 也可以使用列索引名称 df['20100101':'20100103']
head()# 头几行
tail()# 尾几行
loc,iloc方法
loc方法是针对DataFrame索引名称的切片方法,loc使用索引名称切片,iloc使用索引切片
DataFrame.loc[行索引名称或条件, 列索引名称]
DataFrame.iloc[行索引位置, 列索引位置]
# 按照索引位置进行查找
df.iloc[0:3,0:2] #第0行到第2行,第0列到第1列
df.iloc[0:3,[0,1]]# 第0列和第1列
df.iloc[0,1]# 0行1列的一个元素
# 按照索引名称查找
df1=df.loc['20100101':'20100104','a':'b']
df1=df.loc['20100101':'20100104',['a','b']]
增加条件的查询
df1=pd.DataFrame(data={'姓名':['lisa','john','cc'],'年龄':[20,14,16]},index=['a','b','c'])
df1['年龄']>15# 条件返回每个 列索引的True 和Fales
#一般都是设定列条件-------------------------------------
# 年龄>15岁的数据
#列条件 以该列条件筛选所需要的行
df1[df1['年龄']>15]
# 列条件为姓名,且年龄大于15的 行
df1['姓名'][df1['年龄']>15]
# 都是列条件
df1.loc[df1['年龄']>15,'姓名']
4.数据排序
df.sort_index(axis=,ascending=) #axis为0/1的参数,表示按行/按列排序;
df.sort_values(by=,ascending=) #by表示按哪一个columns参数排序。
#ascending为boolean参数,False表示降序,True表示升序。
# 按照索引排序
df_index_sort=df.sort_index(axis=0,ascending=False)
# 按照数据中的某一列排序
df_values_sort=df.sort_values(by='a',ascending=False)
# 合并数据
data=pd.merge(pd.merge(users,ratings),movies)
3.Pandas获取数据
read_table #文本文件
read_csv #读取csv文件
pandas.read_table(filepath_or_buffer, sep=’\t’, header=’infer’, names=None, index_col=None, dtype=None, engine=None, nrows=None)
参数名称 | 说明 |
filepath | string。代表文件路径。无默认。该字符串可以是一个URL。 |
sep | 接收string。代表分隔符。read_csv默认为“,”,read_table默认为制表符“[Tab]”。 |
header | int或sequence。表示是否将某行数据作为列名。默认为infer,表示自动识别。 |
names | array。表示列名。默认为None。 |
index_col | int、sequence或False。表示选择哪***列作为行索引***,取值为sequence则代表多重索引。默认为None。 |
dtype | dict。代表写入的数据类型(列名为key,数据格式为values)。默认为None。 |
engine | c或者python。代表数据解析引擎。默认为c。 |
nrows | int。表示读取前n行。默认为None。 |
注意事项:
header参数是用来指定列名的,如***果是None,我们需要添加一个默认的列名***。采用names设置
encoding代表文件的编码格式,常用的编码有utf-8、utf-16、gbk、gb2312、gb18030等。
存储数据
DataFrame.to_csv(path_or_buf=None, sep=’,’, na_rep=”, columns=None, header=True, index=True,index_label=None,mode=’w’,encoding=None)
na_rep string。代表缺失值。默认为“”。
columns list。代表写出的列名。默认为None。
header boolean,代表是否将列名写出。默认为True。
index boolean,代表是否将行名(索引)写出。默认为True。
index_labels sequence。表示行索引名。默认为None。
mode string。代表数据写入模式。默认为w。
4.pandas描述性统计分析概述
数值型特征的描述性统计
方法名称 | 说明 | 方法名称 | 说明 |
min | 最小值 | max | 最大值 |
mean | 均值 | ptp | 极差 |
median | 中位数 | std | 标准差 |
var | 方差 | cov | 协方差 |
sem | 标准误差 | mode | 众数 |
quantile | 四分位数 | count | 非空值数目 |
describe | 描述统计 |
describe,能够一次性得出数据框所有数值型特征的非空值数目、均值、四分位数、标准差。
cov各个维度偏离其均值的程度
类别型特征的描述性统计
- 描述类别型特征的分布状况,可以使用频数统计表。pandas库中实现***频数统计的方法为 value_counts。***
- describe支持对数据进行描述性统计,四个统计量分别为
列非空元素的数目,
类别的数目,
数目最多的类别,
数目最多类别的数目
5.pandas统计分析
- 使用分组聚合方式进行组内计算
- 创建数据透视表
- 交叉表
5.1 分组groupby
Dataframe.groupby()
参数名称 | 说明 |
by | list,string,mapping或generator。用于确定进行分组的依据。无默认。 |
axis | int。表示操作的轴向,默认对***行进行操作。默认为0。*** |
level | int或者索引名。代表标签所在级别。默认为None。 |
as_index | boolearn。表示聚合后的聚合标签是否以DataFrame索引形式输出。默认为True。 |
sort | boolearn。表示是否对分组依据分组标签进行排序。默认为True。 |
group_keys | boolearn。表示是否显示分组标签的名称。默认为True。 |
用groupby方法分组后的结果并不能直接查看,而是被存在内存中,输出的是内存地址。类似Series与DataFrame结构,但是pandas提供的一种对象
GroupBy对象常用的描述性统计方法如下。
方法名称 | 说明 | 方法名称 | 说明 |
count | 计算分组的数目,包括缺失值。 | cumcount | 对每个分组中组员的进行标记,0至n-1。 |
head | 返回每组的前n个值。 | size | 返回每组的大小。 |
max | 返回每组最大值。 | min | 返回每组最小值。 |
mean | 返回每组的均值。 | std | 返回每组的标准差。 |
median | 返回每组的中位数。 | sum | 返回每组的和。 |
5.2 聚合函数agg
agg方法求统计量
.agg
func 接收list、dict、function。表示应用于每行/每列的函数。无默认
axis 接收0或1。代表操作的轴向。默认为0。
#所有菜品销量和售价的 总和与均值
detail[['counts','amounts']].agg([np.sum,np.mean])
#段希望只做求均值操作,而对另一个字段则希望只做求和操作,可以使用字典的方式
detail.agg({'counts':np.sum,'amounts':np.mean})
#某个字段的多个统计量,某些字段则只需要求一个统计量
detail.agg({'counts':np.sum,'amounts':[np.mean,np.sum]})
demon
#给定以下数据
df = pd.DataFrame({'A': [1, 1, 2, 2],
'B': [3, 4, 3, 4],
'C': np.random.randn(4)})
# print(df)
# 按照A列分组后聚合求最小值 df1接收
df1=df.groupby('A').agg('min')
print(df1)
# 按照A列分组和B列分组后聚合求最小值和最大值 df2接收
df2=df.groupby(['A','B']).agg(['min','max'])
print(df2)
# 按照A列分组后聚合后对B列求最小值和最大值,
# # 对C列求和,df3接收
df3=df.groupby('A').agg({'B':['min','max'],'C':'sum'})
print(df3)
5.3 透视表
利用pivot_table函数可以实现透视表
pands.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
参数名称 | 说明 |
data | 接收DataFrame。表示创建表的数据。无默认。 |
values | 接收字符串。用于指定想要聚合的数据字段名,默认使用全部数据。 |
index | 接收string或list。表示行 分组键。默认为None。 |
columns | 接收string或list。表示列 分组键。默认为None。 |
aggfunc | 接收functions。表示 聚合函数。默认为mean。 |
margins | 接收boolearn。表示汇总(Total)功能的开关,设为True后结果集中会出现名为“ALL”的行和列。默认为True。 |
dropna | 接收boolearn。表示是否删掉全为NaN的列。默认为False。 |
# 1每个经理的业绩
pd.pivot_table(df,index="经理",values=["价格"],aggfunc=[np.sum])
# 2每个经理下的销售代表业绩 #层级行索引
pd.pivot_table(df,index=["经理","销售代表"],values=["价格"],aggfunc=np.sum)
# 3每个经理下的销售代表业绩 与2展示方式不同!列索引为销售代表,内容数据为销售业绩
pd.pivot_table(df,index=["经理"],columns=['销售代表'],values=["价格"],fill_value=0,aggfunc=np.sum)
# 4如果我们希望看到按产品细分的销售额,则columns参数允许我们定义一个或多个列
# columns是可选的,它提供了一种额外的方式来细分你关心的实际值。聚合功能将应用于values的数据
pd.pivot_table(df,index=["经理","销售代表"],values=["价格"],fill_value=0,
columns=["产品"],aggfunc=[np.sum])
# 5拼接两种聚类
pd.pivot_table(df,index=["经理"],columns=["产品"],values=["数量","价格"],fill_value=0,aggfunc={"数量":np.sum,"价格":np.mean})
5.4 交叉表
交叉表是一种特殊的透视表,主要用于计算***分组频数***。利用pandas提供的crosstab函数可以制作交叉表
交叉表是透视表的一种
pd.crosstab()
#参数,同透视表
index
columns
aggfunc
dropna
margings boolearn。默认为True。汇总(Total)功能的开关,出现名为“ALL”的行和列
demo
#交叉表练习
import pandas as pd
import numpy as np
data = pd.DataFrame({'Sample': range(1, 11), 'Gender': ['Female', 'Male', 'Female', 'Male', 'Male', 'Male', 'Female', 'Female', 'Male', 'Female'],
'Handedness': ['Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed', 'Left-handed', 'Right-handed', 'Right-handed']})
data
# 统计不同性别的用手习惯
pd.pivot_table(index='Gender',columns='Handedness',data=data,values='Sample',aggfunc=len,margins=True)
# 用交叉表 对于分类之后的样本数据进行数量计数
pd.crosstab(index=data['Gender'],columns=data.Handedness,margins=True)
# 注意行索引名和列索引名 与行索引列索引的区别
# 一般 index 填写行索引名 columns列索引名
Panda数据分析小结
简单分析方法:(现状分析或问题定位)掌握数理统计等知识完成基础的业务数据分析,提取有价值的信息,形成有效的结论。比如:描述性统计分析,探索性数据分析
深层业务逻辑建模分析:(未来数据预测)使用数据挖掘算法中的分类、聚类、回归等方法搭建模型,分析完成复杂的数据分析工作,重点挖掘数据价值,寻找模式与规律。
6.描述性统计分析
描述性统计分析:描述性统计分析要对调查总体所有变量的有关数据做统计性描述,主要包括数据的集中趋势分析、连续型数据分布形态、类别型数据的频数分析
- 集中趋势的描述性统计量
均值:算术平均数,数据的平均水平,是集中趋势中波动最小、最可靠的指标,但是均值容***易受到极端值(极小值或极大值)的影响。***
中位数:是指当一组数据按照顺序排列后,位于中间位置的数,不受极端值的影响,对于定序型变量,中位数是最适合的表征集中趋势的指标。
众数:是指一组数据中出现次数最多的观测值,不受极端值的影响,常用于***描述定性数据的集中趋势*** - 离散程度的描述性统计量
最大值和最小值:…
极差:又称全距,是一组数据中的最大观测值和最小观测值之差,记作R,一般情况下,极差越大,离散程度越大,其值容易受到极端值的影响。
方差和标准差:是描述一组数据离散程度的最常用、最适用的指标,值越大,表明数据的离散程度越大。 - 频数分析
频数分布分析:主要通过***频数分布表***来描述数据的分布特征。 - 连续型数据分布形态
7.探索性统计分析
EDA(Exploratory Data Analysis)
- 在统计学上,EDA是指通过分析数据,***来总结数据主要特征***的方法,可视化方法是使用较多的方式
- 这个过程并不一定需要统计模型,主要目的是在尽量少的先验假设下,心无杂念的让数据告诉我们一切,使用可视化和定量方法来了解数据所讲述的故事,在其中寻找线索、逻辑、问题或研究领域等线索。
- 主要目的:
1、寻找数据特征之间的关系、鉴别特征之间有趣的或者意想不到的关系
2、分析并希望找出与结果有关的特征,进而完成特征工程的构建
3、是否需要更多数据做数据分析的支撑
tips:就是寻找列与列的关系
二.Pands数据预处理
数据预处理大体分为三个步骤
1.数据清洗:数据缺失值处理 pd.notnull,差值等
2.转换数据:将字符型(对象型)量化为数值型,数据one-hot处理:逻辑回归算法需要传入的数据是数值型
3.标准化数据:对数据进行标准化处理,处理异常值
1.合并数据
将x轴或将y轴拼接以达到合并效果
pd,concat()
# 参数
objs Series,DataFrame的组合。表示参与连接的pandas对象的列表的组合。无默认。
axis 0或1。表示连接的轴向,默认为0y
join inner或outer。表示其他轴向上的索引是按交集(inner)还是并集(outer)进行合并。默认为outer。
#----------------------------------------------
join_axes Index对象。表示用于其他n-1条轴的索引,不执行并集/交集运算。
ignore_index boolean。表示是否不保留连接轴上的索引,产生一组新索引range(total_length)。默认为False。
keys sequence。使用传递的键作为最外层来构造层次索引。加上一个层次的key来识别数据源自于哪张表
names list。生成的层次结构索引中的级别的名称。默认为None。
verify_integrity boolearn。表示是否检查结果对象新轴上的重复情况,如果发现则引发异常
1.1横向堆叠合并数据
当axis=1的时候,concat做横向合并 ,x轴拼接
列拼接,对行求并或交
1.2纵向堆叠合并数据
当axis=0的时候,concat做纵向合并,y轴拼接
行拼接,对列交或并
纵向堆叠append方法
append方法也可以用于纵向合并两张表。但是append方法实现纵向表堆叠有一个前提条件,那就是两张表的列名需要完全一致。
df.append()
# 参数
other DataFrame或Series。表示要添加的新数据。
ignore_index boolean。如果输入True,会对新生成的DataFrame使用新的索引(自动产生)而忽略原来数据的索引
verify_integrity boolean。如果输入True,那么当ignore_index为False时,会检查添加的数据索引是否冲突,如果冲突,则会添加失败
demo
import numpy as np
import pandas as pd
#定义资料集
df1 = pd.DataFrame(np.ones((3,4)), columns=['a','b','c','d'])
df2 = pd.DataFrame(np.ones((3,4)), columns=['a','b','c','d'])
df3 = pd.DataFrame(np.ones((3,4)), columns=['a','b','c','d'])
print(df1)
print(df2)
print(df3)
# concat基本参数练习
#res接收 concat纵向合并 注意参数axis合并方向
res=pd.concat(objs=[df1,df2,df3],axis=0)
res
#承上一个例子,并将并将ignore_index设定为True:重置index
res=pd.concat(objs=[df1,df2,df3],axis=0,ignore_index=True)
res
#concat_join参数的练习
# join (合并方式) 如果为’inner’得到的是两表的交集,如果是outer,得到的是两表的并集
#定义资料集
df1 = pd.DataFrame(np.ones((3,4))0,columns=['a','b','c','d'], index=[1,2,3])
df2 = pd.DataFrame(np.ones((3,4))1,columns=['b','c','d','e'], index=[2,3,4])
# join (合并方式) 如果为’inner’得到的是两表的交集,如果是outer,得到的是两表的并集
res=pd.concat(objs=[df1,df2],axis=0,join='outer',sort=True,keys=['df1','df2'],names=['df_name','row_id'])
res
# 内合并
res=pd.concat(objs=[df1,df2],axis=0,join='inner',ignore_index=True)
res
# append合并案例练习
# append合并
#定义资料集
df1 = pd.DataFrame(np.ones((3,4))0, columns=['a','b','c','d'])
df2 = pd.DataFrame(np.ones((3,4))1, columns=['a','b','c','d'])
#要求将df2合并到df1的下面,以及重置index,并打印出结果
df1.append(df2,ignore_index=True)
1.3主键合并
和数据库的join一样,merge函数也有左连接(left)、右连接(right)、内连接(inner)和外连接(outer)
tips
左连接,以左边的表格为参考,保留左表所有数据,再以两表中的其中一个字段作为合并的主键,可能会增加(重复),或者丢失右表的数据
内连接 交集 外连接 并集
vpandas.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False)
参数名称 | 说明 |
left | 接收DataFrame或Series。表示要添加的新数据。无默认。 |
right | 接收DataFrame或Series。表示要添加的新数据。无默认。。 |
how | 接收inner,outer,left,right。表示数据的连接方式。默认为inner。 |
on | 接收string或sequence。表示两个数据合并的主键(必须一致)。默认为None。 |
left_on | 接收string或sequence。表示left参数接收数据用于合并的主键。默认为None。 |
right_on | 接收string或sequence。表示right参数接收数据用于合并的主键。默认为None。 |
left_index | 接收boolean。表示是否将left参数接收数据的index作为连接主键。默认为False。 |
right_index | 接收boolean。表示是否将right参数接收数据的index作为连接主键。默认为False。 |
sort | 接收boolean。表示是否根据连接键对合并后的数据进行排序。默认为False。 |
import pandas as pd
import numpy as np
# 依据一组key合并
#定义资料集并打印出
left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'],
'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K4'],
'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']})
left
right
#练习on参数,how参数
#依据key column合并,并打印出结果 res
# res=pd.merge(left,right)
res=pd.merge(left,right,on='key',how='left')
res
## 练习参数left_on,right_index
left = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3'],
'key': ['K0', 'K1', 'K0', 'K1']})
right = pd.DataFrame({'C': ['C0', 'C1'],
'D': ['D0', 'D1']},
index=['K0', 'K1'])
result = pd.merge(left, right, left_on='key', right_index=True, how='left', sort=True)
result
#练习参数left_index,right_index
left = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
'B': ['B0', 'B1', 'B2']},
index=['K0', 'K1', 'K2'])
right = pd.DataFrame({'C': ['C0', 'C2', 'C3'],
'D': ['D0', 'D2', 'D3']},
index=['K0', 'K2', 'K3'])
pd.merge(left,right,how= 'left',left_index=True,right_index=True)
2.数据清洗
2.1检测和处理缺失值
- 清洗数据:缺失值(删除-dropna,替换-fillna,插值-scipy)
- 清洗数据:异常值(3σ原则,箱线图分析)
利用isnull或notnull找到缺失值
df.isnull()
删除法
pandas中提供了简便的删除缺失值的方法dropna,该方法既可以删除观测记录,亦可以***删除特征(当缺失值超过25%)***。
pandas.DataFrame.dropna(self, axis=0, how='any', thresh=None, subset=None, inplace=False)
axis 0或1。表示轴向,0为删除观测记录(行)
how 接收特定string。表示删除的形式。
any表示只要有缺失值存在就执行删除操作。
all表示当且仅当全部为缺失值时执行删除操作。默认为any。
subset array数据。表示进行去重的列∕行。默认为None,表示所有列/行。
inplace boolean。表示是否在原表上进行操作
替换法
- 替换法是指用一个特定的值替换缺失值。
- 缺失值所在特征为数值型时,通常利用其均值、中位数和众数等描述其集中趋势的统计量来代替缺失值。(固定值,最近临插补,回归,插值函数)
- 缺失值所在特征为类别型时,则选择使用众数来替换缺失值
pandas库中提供了缺失值替换的方法名为fillna
pandas.DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None)
# 参数
value scalar,dict,Series或者DataFrame。表示用来替换缺失值的值
method string。backfill或bfill表示使用下一个非缺失值填补缺失值。pad或ffill表示使用上一个非缺失值填补缺失值。默认为None。
limit int。表示填补缺失值个数上限,超过则不进行填补。默认为None。
demo
import pandas as pd
import numpy as np
# 处理丢失数据
dates = pd.date_range('20130101', periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates, columns=['A','B','C','D'])
df.iloc[0,1] = np.nan
df.iloc[1,2] = np.nan
# df1接收,去掉有 NaN 的行, 可以使用 dropna 一旦出现NaN就去除整行
df1=df.dropna(axis=0,how='any')
df1
# df2接收,如果是将 NaN 的值用其他值代替, 比如代替成 0:
df2=df.fillna(value=0)
df2
# b列数据,填补平均值
df['B']=df['B'].fillna(df['B'].mean())
df
# c列数据,填补平均值
df['C']=df['C'].fillna(df['C'].mean())
df
# df3接收,判断是否有缺失数据 NaN, 为 True 表示缺失数据:
df3=df.isnull()
df3
#每一列的缺失数据
# df4=df.isnull().sum(axis=0)
# df4
#每一行的缺失数据
df5=df.isnull().sum(axis=1)
df5
#整个表的缺失数据
df5.sum()
插值法
scipy提供了插值算法可以通过一组散点得到一个符合一定***规律插值器函数***。这样当我们给插值器函数更多未知x,插值函数将会返回相应的y用于填补缺失值。
scipy提供的插值方法如下:
import scipy.interpolate as si
func = si.interp1d(
离散水平坐标,
离散垂直坐标,
kind=插值算法(缺省为线性插值)
)
demon
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate as si
x = [30, 40, 50, 60, 65]
y = [100, 120, 135, 155, 170]
plt.scatter(x, y)
xs = np.linspace(min(x), max(x), 200)
# 通过这些散点,构建一个线性插值函数
linear = si.interp1d(x, y, kind='linear')
print(linear(45))
ys = linear(xs)
plt.plot(xs, ys,color='r')
plt.show()
import numpy as np
# interpolation 插值
from scipy.interpolate import interp1d # 注意是1,2,3,的1 不是l,m,n,的l
import matplotlib.pyplot as plt
x = np.linspace(0, 10, num=11, endpoint=True) # 0-10之间 11个点
y = np.cos(-x ** 2 / 9.0) # 函数
f = interp1d(x, y)
f2 = interp1d(x, y, kind='cubic')
# 'zero', 'slinear', 'quadratic', 'cubic' 分别是:阶梯插值 线性插值 二阶曲线插值 三阶曲线插值
xnew = np.linspace(0, 10, num=41, endpoint=True) # 0-10之间 41个点 最后一个点存在
plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--') # o表示圆点 -表示实线 --表示虚线
plt.legend(['data', 'linear', 'cubic'], loc='best') # 图释
plt.show() # 展示
3.标准化数据
1.当数据取值范围较大
2.消除单位带来的影响
3.加快算法模型速度
离差标准化
将样本转换到 0-1之间
数据的***整体分布情况***并不会随离差标准化而发生改变,原先取值较大的数据,在做完离差标准化后的值依旧较大。
当数据和最小值相等的时候,通过离差标准化可以发现数据变为0。
标准差标准化
符合正态分布时使用
demon
import numpy as np
import pandas as pd
np.random.seed(1)
df = pd.DataFrame(np.random.randn(4, 4) 4 + 3)
df
# 离差标准化
df_norm=(df-df.min())/(df.max()-df.min())
df_norm
# 标准差标准化
df_norm1=(df-df.mean())/(df.std())
df_norm1
4.转换数据
哑变处理类别型
部分的算法模型都要求输入的特征为数值型,但实际数据中特征的类型不一定只有数值型,还会存在相当一部分的类别型,这部分的特征需要经过哑变量处理才可以放入模型之中,(类别型数据编码化)
pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None)
参数名称 | 说明 |
data | 接收array、DataFrame或者Series。表示需要哑变量处理的数据。无默认。 |
prefix_sep | 接收string。表示前缀的连接符。默认为‘_’。 |
dummy_na | 接收boolean。表示是否为Nan值添加一列。默认为False。 |
columns | 接收类似list的数据。表示DataFrame中需要编码的列名。默认为None,表示对所有object和category类型进行编码。 |
prefix | 接收string、string的列表或者string的dict。表示哑变量化后列名的前缀。默认为None。 |
哑变量处理特点
虚拟变量,也叫***哑变量和离散特征编码,***可用来表示分类变量、非数量因素可能产生的影响。
***离散特征的编码***分为两种情况:
- 离散特征的取值之间没有大小的意义,比如color:[red,green],那么就使用one-hot编码
- 离散特征的取值有大小的意义,比如size:[X,XL,XXL],那么就使用数值的映射{X:1,XL:2,XXL:3}
- 对于一个类别型特征,若其取值有m个,则经过哑变量处理后就变成了m个二元特征,并且这些特征互斥,每次只有一个激活,这使得数据变得稀疏。
- 对类别型特征进行哑变量处理主要解决了部分算法模型无法处理类别型数据的问题,这在一定程度上起到了扩充特征的作用。由于数据变成了稀疏矩阵的形式,因此也加速了算法模型的运算速度。
demo
import pandas as pd
df = pd.DataFrame([
['green','M','10.2','class1'],
['red','L','13.5','class2'],
['blue','XL','15.3','class1'],
])
df.columns = ['color','size','prize','class label']
df
df.info()
size_mapping={'XL':3,'L':2,'M':1}
df['size']=df['size'].map(size_mapping)
df
class_mapping={label:idx for idx,label in enumerate(set(df['class label']))}
class_mapping
df['class label']=df['class label'].map(class_mapping)
df
pd.get_dummies(df)
知识点补充: enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
seasons=['Spring','Summer','Fall','Winter']
list(enumerate(seasons))
list(enumerate(seasons,start=2))
# 普通for循环
i=0
seq=['one','two','three']
for element in seq:
print (i,seq[i])
i+=1
seq=['one','two','three']
for i,element in enumerate(seq):
print(i,element)
离散化连续型
- 某些模型算法,特别是某些分类算法如***ID3决策树算法和Apriori算法等***,要求数据是离散的,此时就需要将连续型特征(数值型)变换成离散型特征(类别型)。
- 连续特征的离散化就是在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一些***离散化的区间***,最后用不同的符号或整数值代表落在每个子区间中的数据值。
- 因此离散化涉及两个子任务,即***确定分类数***以及如何将连续型数据***映射***到这些***类别型数据***上。
pandas.cut(x, bins, right=True, labels=None, retbins=False)
参数名称 | 说明 |
x | 接收数组或Series。代表需要进行离散化处理的数据。无默认。 |
bins | 接收int,list,array,tuple。若为int,代表离散化后的类别数目; 若为序列类型的数据,则表示进行切分的区间,每两个数间隔为一个区间。无默认。 |
right | 接收boolean。代表右侧是否为 闭区间。默认为True。 |
labels | 代表离散化后的各个类别名称 |
retbins | 接收boolean。代表是否返回区间标签。默认为False。 |
import pandas as pd
ages=[20,22,34,56,34,12,9,43,23,18,45]
bins=[5,10,15,20,25,30,40,45,50,60]
cut_data=pd.cut(x=ages,bins=bins)
cut_data
cut_data.value_counts().plot(kind='barh')
5.数据规约
- 降低无效,错误数据对建模的影响,提高建模的准确性
- 少量且具有代表性的数据将大幅缩减数据挖掘所用的时间
- 减低储存数据成本
属性规约
属性合并来创建新属性维数,或者直接删除不相关的属性来减少数据维数
目的是寻找最小的属性子集并确保新数据子集的概率分布尽可能的接近原来的数据集概率分布
数值规约
指的是通过选择替代的,较小的数据来减少数据量
- 有参数:***使用模型***来评估数据,只存放参数,不存放实际数据
eg:线性回归/多元回归 - 无参数:存放实际数据,直方图/聚类/抽样
(1)直方图。如一连串的数据,通过绘制直方图(R中用hist()函数绘制直方图),分为“315”、“1628”、“29~41”三个范围。
(2)聚类。将对象划分为簇,使一个簇中的对象相互“相似”,而与其他簇中的对象“相异”,用数据的簇替换实际数据。
(3)抽样。有放回/无放回