文章内容有点多,可收藏慢慢观看🥰
概念介绍
pandas模块介绍
pandas是python的一个数据分析包。。pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。pandas的名称来自于面板数据(panel data)和Python数据分析(data analysis)。panel data是经济学中关于多维数据集的一个术语,在pandas中也提供了panel的数据类型。 扩展库pandas(Python Data Analysis Library)是基于Numpy的数据分析模块,提供了大量标准数据模型和高效操作大型数据集所需要的工具,可以说pandas是使得Python能够成为高效且强大的数据分析环境的重要因素之一。
pandas提供四种数据结构:
- Series::带标签的一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很接近,其区别在于List中的元素可以为不同的数据类型,而array和Series则只允许存储相同的数据类型,这样可以更为有效的使用内存,提高运算效率。
- DataFrame:带标签且大小可变的二维表格结构。
- Time-Series:以时间为索引的Series。
- Panel:带标签且大小可变的三维数组,可以理解为DataFrame的容器。
Series和DataFrame
Series简介
Series是一个带标签的一维数组结构,它可以存入任意一种Python的数据类型。该对象与Numpy中的一维array类似,允许存储相同的数据类型。
在Series中,标签不必是唯一的,但是必须是可迭代的数据类型,同时支持整数和基于标签的索引,并且它提供了许多用于执行涉及到索引的操作的方法,在此中,多维数组对象的统计方法被重写,以自动排除丢失的数据(现在多为NaN),Series之间的操作(+、-、/、*)基于其相关的索引值,它们并不需要保证长度相同。最终的索引将会是两个索引的并集。 创建一个Series的最基本方法是:
s = pd.Series(data,index = index)
Series就如同列表一样,一系列数据,每个数据对应一个索引值。比如这样一个列表:[7,6,9],如果跟索引值写到一起,就是:
在有些时候,需要把它竖过来表示:
DataFrame简介
pandas是Python环境下最有名的数据统计包,而DataFrame翻译为数据框(数据帧),它是带标签的二维数据结构,即在DataFrame中,数据是以行和列的表格方式来排列的。它是一种数据组织和呈现的方式,简单的说就是一种Python中的表格,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共用同一个索引)。DataFrame中面向行和面向列的操作基本上是平衡的。其实,DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构)。
DataFrame的功能特点:
- 潜在的列是不同的类型
- 大小可变
- 标记轴(行和列)
- 可以对行和列执行算数运算
可以通过以下构造函数来创建一个DataFrame(下面有详细的补充):
pandas.DataFrame( data, index, columns, dtype, copy)
各参数的含义如图所示:
DataFrame的常用属性方法
创建DataFrame
在pandas中,DataFrame可以使用各种输入进行创建,例如列表、字典、系列、Numpy ndarray以及另一个数据帧(DataFrame)等。
- 创建一个空的DataFrame
import pandas as pd #导入pandas库,取别名为pd
df=pd.DataFrame() #调用DataFrame()函数
print(df)
#输出结果:
Empty DataFrame
Columns: []
Index: []
- 从列表中创建DataFrame
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,columns=['Country','Population(thousands)']) #columns为列标签名称
print(df)
我们可以指定DataFrame函数中的index参数来改变索引值:
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(in thousands)']) #指定了index
print(df)
在未指定index值时,index默认是从0开始的数字。现在我们指定为了a,b,c,d,其运行结果为:
3. 从ndarrays/Lists的字典创建DataFrame
从ndarrays/Lists的字典创建DataFrame。用此方法进行创建时,要保证所有的ndarrays必须具有相同的长度。如果传递了索引(index),则索引的长度应等于数组的长度。如果没有传递索引,则默认情况下,索引将为range(n),其中n为数组长度。
import pandas as pd #导入pandas库,取别名为pd
data={'Country':['China','USA','Japan','India'],'Population(thousands)':[1328474,302841,127953,1151751]} #字典的键对应列名,字典的值对应每一列的内容
df=pd.DataFrame(data)
print(df)
运行结果:
4. 从series系列的字典来创建DataFrame
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=[0,1,3]),'Population(thousands)':pd.Series([1328474,302841,127953,1151751])} #利用Series赋值
df=pd.DataFrame(data)
print(df)
执行结果如下,可以看到,在第一个Series系列中,并没有传递标签“2”,所以在图8所示结果中,对于“2”标签,附加了NaN。因为在pandas中空值表示为NaN。
DataFrame常用方法
- 列选择,即从数据帧(DataFrame)中的数据中选择一列。
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=[0,1,3]),'Population(thousands)':pd.Series([1328474,302841,127953,1151751])} #利用Series赋值
df=pd.DataFrame(data)
print(df['Country']) #打印Country列
print(df['Population(thousands)']) #打印Population(thousands)列
- 列添加,即向现有数据帧(DataFrame)中添加一个新列。
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=[0,1,3]),'Population(thousands)':pd.Series([1328474,302841,127953,1151751])} #利用Series赋值
df=pd.DataFrame(data)
print(df)
df['income_per_person']=pd.Series([4091,41674,2126],index=[0,1,3]) #添加列(人均收入)
print(df)
df['total']=df['Population(thousands)']*df['income_per_person'] #添加列(人口*人均收入=total总收入)
print(df)
- 列删除,即删除列或者弹出列
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=[0,1,3]),'Population(thousands)':pd.Series([1328474,302841,127953,1151751])} #利用Series赋值
df=pd.DataFrame(data)
df['income_per_person']=pd.Series([4091,41674,2126],index=[0,1,3]) #添加列(人均收入)
df['total']=df['Population(thousands)']*df['income_per_person'] #添加列(人口*人均收入=total总收入)
print(df)
del df['total'] #删除列
df.pop('Population(thousands)') #弹出(删除)列
print(df)
- 行标签选择,即可以通过将行标签传递给loc()函数来选择行。行按整数位置选择,即可以通过将整数位置传递给iloc()函数来选择行
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=['a','b','d']),'Population(thousands)':pd.Series([1328474,302841,127953,1151751],index=['a','b','c','d'])} #利用Series赋值
df=pd.DataFrame(data)
print(df.loc['b']) #loc通过行标签索引数据
print(df.iloc[1]) #iloc通过行号索引行数据
- 行切片,可以使用“:”运算符选择多行
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=['a','b','d']),'Population(thousands)':pd.Series([1328474,302841,127953,1151751],index=['a','b','c','d'])} #利用Series赋值
df=pd.DataFrame(data)
print(df[1:3]) #打印1,2两行(行数从0数起)
- 附加行,即使用append()函数将新行添加到 DataFrame。此功能将附加行结束
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=['a','b','d']),'Population(thousands)':pd.Series([1328474,302841,127953,1151751],index=['a','b','c','d'])} #利用Series赋值
data2={'Country':pd.Series(['Spain','Zambia'],index=['e','d']),'Population(thousands)':pd.Series([43887,11696],index=['e','d'])} #利用Series赋值
df=pd.DataFrame(data)
df2=pd.DataFrame(data2)
df=df.append(df2) #使用append()函数添加行
print(df)
- 删除行,使用索引标签从DataFrame中删除或删除行。如果标签重复,则会删除多行
import pandas as pd #导入pandas库,取别名为pd
data={'Country':pd.Series(['China','USA','India'],index=['a','b','d']),'Population(thousands)':pd.Series([1328474,302841,127953,1151751],index=['a','b','c','d'])} #利用Series赋值
df=pd.DataFrame(data)
print(df)
df=df.drop('c') #删除行
print(df)
数据访问
在pandas中进行数据访问和修改时要借助DataFrame(数据帧)进行的。
主要有三种索引函数来进行数据访问:
- loc:标签索引,行和列的名称,快捷方式为at;
- iloc:整形索引(绝对位置索引),绝对意义上的几行几列,起始索引为0,快捷方式为iat;
- ix:iloc和loc的整合
以四个国家的人口数据为例,基础数据格式:
loc——通过自定义索引获取数据
- 通过loc按行标签(即自定义的行名、行索引)选取某行数据
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
print(df)
print('\n')
print(df.loc['a']) #打印‘a’行(默认所有列)
print(df.loc['a'],:) #打印‘a’行
loc可以接收行标签和列标签两个参数,如过要选取某行的数据,那么默认是选取所有列,即df.loc['a']
和df.loc['a',:]
是等价的:
- 通过loc按列标签选取某列数据
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
print(df)
print('\n')
print(df.loc[:,'Country']) #打印Country列
在使用loc选取列的时候,不能省略行标签的指定使用(:)
表示所有行,需要明确的指明:
- 通过loc按行、列标签选取指定的行和列的数据
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
print(df)
print('\n')
print(df.loc['a':'c','Country']) #打印a到c行的Country列
- 可以在访问数据的同时改变数据
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
print(df)
print('\n')
df.loc['c','Country']='None' #将c行Country列的数据改为None
print(df)
iloc——通过数字索引获取数据
- iloc使用方法和loc基本一致,区别在于iloc使用的时数字索引
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
print(df)
print('\n')
print(df.iloc[2,1]) #第2行第1列的数据(行和列都是从0数起)
ix——loc和iloc结合
ix时loc和iloc的结合,可以混合使用数字和自定义的标签进行索引
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
print(df)
print('\n')
print(df.ix['c',1]) #打印c行1列的数据(从0数起)
print(df.ix[2,'Population(thousands)']) #打印2行Population(thousands)列的数据(从0数起)
其他索引方法——Boolean索引
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
print(df)
print('\n')
df_2=df['Population(thousands)']>1000000 #是否大于
print(df_2)
df_3=df[df['Population(thousands)']>1000000] #大于该值的数据
print(df_3)
文件读取
使用pandas存储数据
在使用DataFrame的to_csv保存文件的时候,会默认使用逗号作为分隔符,如果没有设置行列索引,也没有禁用行列索引保存的话,保存文件的时候,会默认加上由0开始的行列索引。通过设置to_csv函数的sep参数可以修改默认保存文件时候的分隔符。主要参数如下:
(1)路径 path_or_buf
(2)分隔符 sep(default ”,”)
(3)替换空值 na_rep (default ‘’)
(4)格式 float_format
(5)是否保留某列数据 cols (default None)
(6)是否保留列名 header(default True)
(7)是否保留行索引 index (default True)
练习:
- 创建一个DataFrame类型数据,使用to_csv函数将它保存到文件中
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],[None,None],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
df.to_csv('data_csv') #保存到data_csv文件中
-
打开data.csv文件
data_csv文件中的数据是通过(,)逗号分隔的,这就是使用to_csv()函数保存的效果。其中的空值(None)在保存的时候被省略掉。 -
可以通过设置to_csv()函数的sep参数修改分隔符。通过设置na_rap参数替换空值。比如我们可以把分隔符(,)逗号改成(\t)制表符。设置na_rap参数修改为NULL,如此一来,数据中如果存在空值的话保存到文件中就会显示为NULL
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],[None,None],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
df.to_csv('data_table',sep='\t',na_rep='NULL') #保存到data_table文件中,(\t)制表符作为分隔符,空值保存为NULL
- 如果不想要保存行列标签我们可以设置header(列标签)设置为None,index(行标签)设置为None
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],[None,None],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,index=['a','b','c','d'],columns=['Country','Population(thousands)']) #指定了index
df.to_csv('data_no',header=None,index=None) #保存到data_no文件中,不保存列标签和行标签
使用pandas读取数据
和Python按字节读取文件相比,pandas读取文件是按块读取的,在读取文件时,pandas使用pandas.read_csv(filename,kwds)进行,在调用过程中,用到了一个重要的类-TextReader类,这个类负责文件的读写,调用过程中的核心加速都在这里。这个类使用Cython+C编写而成,然后被编译成了parser.pyd文件,用C 进行文件读写,因此速度非常快,在读大文件是会比Python快很多倍,可以显著提高文件读写效率。利用pandas.read_csv(filename,kwds)进行文件读取时,有以下几种方式:
(1)read_csv:从文件、url、文件型对象中加载带分隔符的数据。默认分隔符为逗号(“,”);
(2)read_table:从文件、url、文件型对象中加载带分隔符的数据。默认分隔符为制表符(“\t”);
(3)read_fwf:读取定宽列格式数据(也就是没有分隔符);
(4)read_cliboard:读取剪切板中的数据,可以看做 read_table 的剪切板。在将网页转换为表格时很实用。
练习:
可以用read_csv()函数读出data_csv中的数据并打印出来。也可以使用read_table()函数,不过使用read_table()函数时,sep需要设置为(,)逗号。文件中的空值在pandas中显示NaN
import pandas as pd #导入pandas库,取别名为pd
df_1=pd.read_csv('data_csv')#读取data_csv文件中的数据(默认分隔符为(,)逗号)
print(df_1)
df_2=pd.read_table('data_csv',sep=',')#读取data_csv文件中的数据,(默认分隔符为(\t)制表符)将其设置为(,)逗号
print(df_2)
读取保存到data_table文件中的数据时,可以直接用read_table()函数。也可以使用read_csv()函数,不过使用read_csv()函数时,sep需要设置为(\t)制表符。
import pandas as pd
df_1=pd.read_table('data_table')#读取data_table文件中的数据,(默认分隔符为(\t)制表符)
print(df_1)
df_2=pd.read_csv('data_table',sep='\t')#读取data_table文件中的数据,(默认分隔符为(,)逗号),将其设置为(\t)制表符
print(df_2)
上面两个示例读取的数据前面被默认加上了一列行标签,如果我们不需要这些标签的话,可以指定index_col参数,它会告诉pandas文件中的哪一列是行标签,这样pandas就不会为默认添加了:
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data_csv',index_col=0) #指定第0列是行标签
print(df)
读取存储在data_no文件中无标签的数据是,可以指定names参数,添加标签:
import pandas as pd
df=pd.read_csv('data_no',names=['Cou','Pop']) #设置标签
print(df)
行标签是默认的从0开始的数字,列表签是我们定义的Cou和Pop。
数据清洗
pandas缺失值处理
pandas缺失值概述
我们总会在数据记录里遇到空字段、数据遗漏、数据错误的情况,虽然很讨厌。对于pandas来说,它会把缺失的数值标为NaN,表示None。还有一个类似的符号NaT,它表示的是datetime64型对象。对于NaN这个数值进行算术运算时得到的结果还是NaN。
处理缺失值
在处理缺失值时需要滤除缺失数据,可以使用notnull()函数(与isnull()函数是对应的),丢弃含有缺失值的行的函数是dropna()函数。填充缺失数据时使用最多的就是fillna()函数。count()函数可以查看非缺失值的数量。
1.将带有缺失值的数据保存到文件中
import pandas as pd
data=[['China',1328474],['USA',302841],[None,None],['India',None]] #创建一个列表
df=pd.DataFrame(data,columns=['Country','Population(thousands)']) #指定了index
df.to_csv('data') #保存到桌面上的data文件中
2.处理数据中的缺失值
读取文件中的数据:
import pandas as pd
df=pd.read_csv('data',index_col=0)
print(df)
可以使用count()
函数获取每一列中不是缺失值的数据的数量:
import pandas as pd
df=pd.read_csv('data',index_col=0)
print(df.count())
可以使用isnull()函查看数据是否是缺失值,notnull()函数与之对应:
import pandas as pd
df=pd.read_csv('data',index_col=0)
print(df.isnull())
print(df.notnull())
如果想要填充缺失值,使用fillna()来填充是非常方便的:
import pandas as pd
df=pd.read_csv('data',index_col=0)
df=df.fillna('Done')
print(df)
如果想要直接删除缺失值,可以使用dropna()函数:
import pandas as pd
df=pd.read_csv('data',index_col=0)
df=df.dropna()
print(df)
pandas重复值处理
pandas模块对重复数据的处理
- 利用DataFrame中的重复方法返回一个布尔型的系列,显示各行是否有重复行,没有重复行显示为FALSE,有重复行显示为TRUE
- 再利用DataFrame中的drop_duplicates方法用于返回一个删除了重复行的DataFrame
注意:
如果重复的方法和drop_duplicates方法中没有设置参数,则这两个方法替换会决定全部列,如果在这两个方法中加入了指定的属性名(或称为列名),例如: frame.drop_duplicates([‘state’]),则指定部分列(state列)进行重复项的判断
实际操作:
import pandas as pd #导入pandas库,取别名为pd
data=[['China',1328474],['USA',302841],['Japan',127953],['India',1151751]] #创建一个列表
df=pd.DataFrame(data,columns=['Country','Population(thousands)']) #指定了index
df=df.append(df) #添加行
df.to_csv('data') #保存到data文件中
处理重复值
读取数据:
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data',index_col=0) #读取文件
print(df)
面对这些带有数值的重复数据,我们可以先用sort_values()函数对它们进行排序,如果是相同的数据,那么排序后它们的位置一定相邻:
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data',index_col=0) #读取文件
print(df.sort_values('Population(thousands)')) #对数据排序
也可以是使用duplicated()函数来查看数据是否重复,如果一条数据是第一次出现那么会返回False。如果之前已经出现过了,那么再次出现的话则会返回True:
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data',index_col=0) #读取文件
print(df.duplicated()) #查看是否重复
使用drop_duplicates()函数可以直接删除掉重复的数据项,即在duplicated()返回值为True的数据项,在使用drop_duplicates()函数后会被删除:
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data',index_col=0) #读取文件
print(df.drop_duplicates()) #丢弃重复数据
pandas异常值处理
异常值Outlier
异常值(Outlier) 是指样本中的个别值,其数值明显偏离所属样本的其余观测值。在数理统计里一般是指一组观测值中与平均值的偏差超过两倍标准差的测定值。
Grubbs’test(是以Frank E. Grubbs命名的),又叫Maximum Normed Residual Test,是一种用于单变量数据集异常值识别的统计检测,它假定数据集来自正态分布的总体。
未知总体标准差σ,在五种检验法中,优劣次序为:T检验法、格拉布斯检验法、峰度检验法、狄克逊检验法、偏度检验法。
坏数据的来源
制定数据策略不再是什么新鲜概念。然而很多机构难以获得准确的数据来支撑他们的日常决策。原因就是坏数据。坏数据也称脏数据,是指错误的、具有误导性的、格式非法的信息。不幸的是,没有哪个行业、机构和部门可以免于坏数据的危害。如果未能及早发现和纠正,坏数据将可能导致严重后果。
起初,数据质量仅限于客户关系管理(CRM)系统,而今其复杂程度则已延伸到了结构化客户数据以外的范畴。想要提升数据质量,你必须深入探究,了解导致坏数据的确切原因:
数据丢失:本应包含数据却未填写的空白栏;
数据错误或不准确:信息没有被正确输入或者没有得到正常维护;
数据不对应:数据被错误地输入到了其他栏中;
数据格式不符:数据没有依照记录系统需要进行标准化处理;
数据重复:同一账户、联系人、销售线索等在数据库中记录了不止一次;
数据输入失误:字词、名称或格式方面的拼写错误、打字错误、顺序错误和歧义。
练习:
首先使用numpy科学计算库中的randn()函数,随机生成一个二维数组作为待处理的数据保存到文件中:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(10,8)) #创建对象,生成10行8列的随机数据
df.to_csv('data.csv') #保存数据
处理数据中的异常值
首先从文件中读取并打印查看数据:
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
print(df)
为了解决显示的数据间出现省略的问题,我们可以用下面的方法。在set_option()函数中设置参数display.width为None即可:
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
print(df)
用count()函数可以查看数据中不是空值(NaN)的数量。(函数默认参数为0,参数为0表示按列求值,参数为1表示按行求值):
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
print(df.count()) #打印非空值
使用sum() 按各列求和,df.mean() 按各列求平均值,df.median() 求中位数。(函数默认参数为0,参数为0表示按列求值,参数为1表示按行求值):
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
print(df.sum()) #求和
print(df.mean()) #求均值
print(df.median()) #求中位数
使用var() 求方差,std() 求标准差,mad() 根据平均值计算平均绝对利差。(函数默认参数为0,参数为0表示按列求值,参数为1表示按行求值):
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
print(df.var()) #求方差
print(df.std()) #求标准差
print(df.mad()) #平均绝对利差
使用max()函数求最大值,min()函数求最小值。(函数默认参数为0,参数为0表示按列求值,参数为1表示按行求值):
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
print(df.max()) #求最大值
print(df.min()) #求最小值
使用describe()可以一次性完成上述多种功能。(函数默认参数为0,参数为0表示按列求值,参数为1表示按行求值):
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
print(df.describe())
abs()函数可以对数据绝对值化,all()判断数据是否全部为真,any()判断数据是否存在为真。(函数默认参数为0,参数为0表示按列求值,参数为1表示按行求值):
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
tem=df.abs()<1 #绝对值小于1的数据
print(tem)
print(tem.all())
print(tem.any())
假如通过分析之后或者因为主观因素,我们最终确定在区间(-1,1)之间的数据是正确的数据。那么凡是绝对值大于等于1的值都应该被舍弃或者被修改正确。那么我们通过如下操作,将异常值修改。(示例中仅将异常值修改为均值,实际修改方式因情况而异):
import pandas as pd #导入pandas库,取别名为pd
df=pd.read_csv('data.csv',index_col=0) #读取数据,指定其中第0列为索引
pd.set_option('display.width',None) #不限制显示宽度
mea=df.mean()
df=df[df.abs()<1] #绝对值小于1的数据
df=df.fillna(mea) #填充值
print(df)
红线框中的为修改后的值:
数据集成
使用键参数的DataFrame合并
merge()函数详解
函数体及参数:
merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=('_x', '_y'), copy=True, indicator=False)
left︰ 一个DataFrame对象
right︰ 另一个DataFrame对象
on︰ 要加入的列 (名称)。必须在左、 右综合对象中找到。如果不能通过left_index 和 right_index 是假,将推断 DataFrames 中的列的交叉点为连接键
left_on︰ 从左边的综合使用作为键列。可以是列名或数组的长度等于长度综合
right_on︰ 从右边的综合,以用作键列。可以是列名或数组的长度等于长度综合left_index︰ 如果为True,则使用索引 (行标签) 从左综合作为其联接键。在与多重 (层次) 的综合,级别数必须匹配联接键从右综合的数目
right_index︰ 相同用法作为left_index
how︰ 之一 ‘左’,‘右’,‘外在’、 ‘内部’。默认为内部。
sort︰ 综合通过联接键按字典顺序对结果进行排序。默认值为True,设置为False将提高性能极大地在许多情况下
suffixes︰ 字符串后缀并不适用于重叠列的元组。默认值为(’_x’,’_y’)。
copy︰ 即使重新索引是不必要总是从传递的综合对象,复制的数据(默认值True)。在许多情况下不能避免,但可能会提高性能 / 内存使用情况。可以避免复制上述案件有些病理但尽管如此提供此选项。
indicator︰ 将列添加到输出综合呼吁_merge与信息源的每一行。_merge 是绝对类型,并对观测其合并键只出现在 ‘左’ 的综合,观测其合并键只会出现在 ‘正确’ 的综合,和两个如果观察合并关键发现在两个right_only left_only的值。
学习使用merge()函数
使用merge()函数可以连接两个DateFrame类型数据,连接包含单个连接键的示例如下(其中left和right是原始数据,result是合并后的结果):
import pandas as pd #导入pandas库,取别名为pd
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', 'K3'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right, on='key') #连接键为key
print(result)
包含多个连接键的复杂案例:
默认情况下,只有出现在left和right存在的键(交叉点)默认how=‘inner’。
import pandas as pd #导入pandas库,取别名为pd
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],'key2': ['K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right, on=['key1', 'key2']) #指定连接键
print(result)
(key1,key2)的交集中的数据:
如果我们将how参数设置为outer(使用两个帧中的键的并集),数据就会以并值的形式出现。可以达到如下效果:
import pandas as pd #导入pandas库,取别名为pd
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],'key2': ['K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right,how='outer', on=['key1', 'key2']) #指定连接键
print(result)
如果我们将how参数设置为left,表示仅使用左框架中的键,可以达到如下效果:
import pandas as pd #导入pandas库,取别名为pd
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],'key2': ['K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right,how='left', on=['key1', 'key2']) #指定连接键
print(result)
如果我们将how参数设置为right,那么就是仅使用右框架中的键,可以达到如下效果:
import pandas as pd #导入pandas库,取别名为pd
left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],'key2': ['K0', 'K1', 'K0', 'K1'],'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3']})
right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],'key2': ['K0', 'K0', 'K0', 'K0'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']})
result = pd.merge(left, right,how='right', on=['key1', 'key2']) #指定连接键
print(result)
接下来可以指定indicator参数,如果值为True,将添加_merge列来表示数据来源:
- left_only:仅在’left’框架中
- right_only:仅在’right’框架中
- both:源自两个框架中
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'col1': [0, 1], 'col_left':['a', 'b']})
df2 = pd.DataFrame({'col1': [1, 2, 2],'col_right':[2, 2, 2]})
result=pd.merge(df1, df2, on='col1', how='outer', indicator=True) #指定连接键,并集,显示_merge列
print(result)
如果想要命名_merge列,可以在指定indicator参数时直接对其命名。示例代码如下:
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'col1': [0, 1], 'col_left':['a', 'b']})
df2 = pd.DataFrame({'col1': [1, 2, 2],'col_right':[2, 2, 2]})
result=pd.merge(df1, df2, on='col1', how='outer', indicator=‘indicatorc_column’) #指定_merge列名称
print(result)
学习使用join()函数
join()是一种方便的方法,用于将两个可能不同索引的列组合DataFrames成单个结果 DataFrame。
import pandas as pd #导入pandas库,取别名为pd
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'])
result = left.join(right) #连接
print(result)
join()获取一个可选on参数,该参数可以是一列或多列名称,它指定传递的DataFrame对齐在该列中的列上DataFrame。以下这两个函数调用完全等效:
left.join(right, on=key_or_keys)
pd.merge(left, right, left_on=key_or_keys, right_index=True,how='left', sort=False)
显然,我们可以选择更方便的形式。对于多对一连接(其中一个DataFrame已经通过连接键索引),使用join可能更方便。下面是一个简单的例子:
import pandas as pd #导入pandas库,取别名为pd
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 = left.join(right, on='key') #连接
print(result)
轴向连接
学习concat()函数
concat()函数沿轴执行连接操作的所有繁重工作,同时在其他轴上执行索引,可选集合逻辑并集或交集。
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)
参数说明:
objs: series,dataframe或者是panel构成的序列lsit
axis: 需要合并链接的轴,0是行,1是列
join:连接的方式 inner,或者outer
keys:序列,默认值无。使用传递的键作为最外层构建层次索引。如果为多索引,应该使用元组
使用concat()函数
利用concat()函数将三个数据帧df1,df2,df3连接起来:
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']},index=[0, 1, 2, 3])
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],'B': ['B4', 'B5', 'B6', 'B7'],'C': ['C4', 'C5', 'C6', 'C7'],'D': ['D4', 'D5', 'D6', 'D7']},index=[4, 5, 6, 7])
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],'B': ['B8', 'B9', 'B10', 'B11'],'C': ['C8', 'C9', 'C10', 'C11'],'D': ['D8', 'D9', 'D10', 'D11']},index=[8, 9, 10, 11])
frames = [df1, df2, df3]
result = pd.concat(frames) #连接三个数据帧
print(result)
将特定键与切碎的DataFrame的每个片段相关联。我们可以使用keys参数来做到这一点 :
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']},index=[0, 1, 2, 3])
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],'B': ['B4', 'B5', 'B6', 'B7'],'C': ['C4', 'C5', 'C6', 'C7'],'D': ['D4', 'D5', 'D6', 'D7']},index=[4, 5, 6, 7])
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],'B': ['B8', 'B9', 'B10', 'B11'],'C': ['C8', 'C9', 'C10', 'C11'],'D': ['D8', 'D9', 'D10', 'D11']},index=[8, 9, 10, 11])
frames = [df1, df2, df3]
result = pd.concat(frames, keys=['x', 'y', 'z']) #指定片段
print(result)
上一步操作后,结果对象的索引具有分层索引。这意味着我们现在可以按键选择每个块,比如我们可以直接访问y块的数据:
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']},index=[0, 1, 2, 3])
df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],'B': ['B4', 'B5', 'B6', 'B7'],'C': ['C4', 'C5', 'C6', 'C7'],'D': ['D4', 'D5', 'D6', 'D7']},index=[4, 5, 6, 7])
df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],'B': ['B8', 'B9', 'B10', 'B11'],'C': ['C8', 'C9', 'C10', 'C11'],'D': ['D8', 'D9', 'D10', 'D11']},index=[8, 9, 10, 11])
frames = [df1, df2, df3]
result = pd.concat(frames, keys=['x', 'y', 'z'])
result=result.loc['y'] #访问片段
print(result)
通过指定axis参数,我们可以确定行列维度。axis=0表示列维度,axis=1表示行维度(默认值为0):
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']},index=[0, 1, 2, 3])
df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],'D': ['D2', 'D3', 'D6', 'D7'],'F': ['F2', 'F3', 'F6', 'F7']},index=[2, 3, 6, 7])
result1 = pd.concat([df1, df4], axis=0, sort=False) #列维度
result2 = pd.concat([df1, df4], axis=1, sort=False) #行维度
print(result1)
print(result2)
其中join参数的默认值为outer,表示并集。可以根据需求指定为inner表示交集:
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']},index=[0, 1, 2, 3])
df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],'D': ['D2', 'D3', 'D6', 'D7'],'F': ['F2', 'F3', 'F6', 'F7']},index=[2, 3, 6, 7])
result1 = pd.concat([df1, df4], axis=0, sort=False,join='inner') #列维度、交集
result2 = pd.concat([df1, df4], axis=1, sort=False,join='inner') #行维度、交集
print(result1)
print(result2)
只想重用原始DataFrame中的确切索引的话,可以指定join_axes参数:
import pandas as pd #导入pandas库,取别名为pd
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],'B': ['B0', 'B1', 'B2', 'B3'],'C': ['C0', 'C1', 'C2', 'C3'],'D': ['D0', 'D1', 'D2', 'D3']},index=[0, 1, 2, 3])
df4 = pd.DataFrame({'B': ['B2', 'B3', 'B6', 'B7'],'D': ['D2', 'D3', 'D6', 'D7'],'F': ['F2', 'F3', 'F6', 'F7']},index=[2, 3, 6, 7])
result = pd.concat([df1, df4], axis=1, join_axes=[df4.index]) #使用df4原始索引
print(result)
数据变换
替换值
替换值
有时候我们需要将数据中的某些值替换为其他值,replace()方法就是干这个用的,不同的情况下使用replace的方法也不同。
而且在处理数据的时候,很多时候会遇到批量替换的情况,如果一个一个去修改效率过低,也容易出错。replace()是很好的方法。
Series替换值
定义一组Series数据:
import pandas as pd #导入pandas库,取别名为pd
data = pd.Series([1,-999,2,-999,-1000,3])
print(data)
现在想要将数据中的-999替换成空值NaN:
import pandas as pd #导入pandas库,取别名为pd
import numpy as np #导入numpy库,取别名为np
data = pd.Series([1,-999,2,-999,-1000,3])
data=data.replace(-999,np.nan) #替换为空值
print(data)
还可用replace()函数将多个不同的值替换为同一个值,比如说这组数据中的-999和-1000可以全部替换为NaN:
import pandas as pd #导入pandas库,取别名为pd
import numpy as np #导入numpy库,取别名为np
data = pd.Series([1,-999,2,-999,-1000,3])
data=data.replace([-999,-1000],np.nan) #多个数据替换为一个数据
print(data)
如果需要将不同的值替换为相应不同的值,比较一般的方法就是多调用几次replace()函数。进阶的用法就是使用列表或者字典:
import pandas as pd #导入pandas库,取别名为pd
import numpy as np #导入numpy库,取别名为np
data = pd.Series([1,-999,2,-999,-1000,3])
data.replace([-999,-1000],[np.nan,0],inplace=True) #多个数据替换为多个数据,指定inplace参数可以将改变了的数据保存到源数据中
data2=data.replace({-999:np.nan,-1000:0}) #多个数据替换为多个数据
print(data1)
print(data2)
DataFrame替换值
import pandas as pd #导入pandas库,取别名为pd
df = pd.DataFrame({'A': [1, 2, 3, 4,5],'B': [1, 3, 5, 7, 9],'C': ['a', 'b', 'c', 'd', 'e']})
print(df)
使用replace()函数将数据桢中的所有的5替换为0。指定inplace参数为True,这样替换部分数据就会写入源数据:
import pandas as pd #导入pandas库,取别名为pd
df = pd.DataFrame({'A': [1, 2, 3, 4,5],'B': [1, 3, 5, 7, 9],'C': ['a', 'b', 'c', 'd', 'e']})
df.replace(5,0,inplace=True)
print(df)
替换多个值的方法和Series中一样,也是即可以用列表也可以用字典,这里以列表为例将1和5的位置进行调换:
import pandas as pd #导入pandas库,取别名为pd
df = pd.DataFrame({'A': [1, 2, 3, 4,5],'B': [1, 3, 5, 7, 9],'C': ['a', 'b', 'c', 'd', 'e']})
df.replace([1,5],[5,1],inplace=True)
print(df)
重命名轴索引
rename()函数
rename(mapper=None,index=None,columns=None,axis=None,copy=True,inplace=False,level=None)
函数或字典值必须是唯一的(1对1)。未包含在dict或Series中的标签将保留原样。列出的额外标签不会引发错误。
axis:可选轴与目标mapper。可以是轴名称(‘index’,‘columns’)或数字(0,1)。默认为’index’。
copy : 默认值为True,复制基础数据。
inplace:默认为False。表示是否返回新的DataFrame。
level:默认为None。如果是MultiIndex,则只重命名指定级别的标签。
返回:已经重命名的DataFrame。
直接赋值重命名
import pandas as pd #导入pandas库,取别名为pd
df=pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]}) #赋值
print(df)
df.columns=['c','b']
df.index=[1,2,3]
print(df)
使用rename()函数重命名轴索引
利用rename()函数,指定columns参数,通过字典方式来重命名列索引:
import pandas as pd #导入pandas库,取别名为pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
print(df)
df.rename(columns={"A": "a", "B": "c"},inplace=True)
print(df)
使用以下方法完成大小写的转换:
import pandas as pd #导入pandas库,取别名为pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
print(df)
df.rename(str.lower, axis='columns',inplace=True) #str.lower表示转换为小写,str.upper表示转换为大写
print(df)
指定axis参数为index,表示行索引,来进行修改:
import pandas as pd #导入pandas库,取别名为pd
df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})
print(df)
df.rename({1: 2, 2: 4}, axis='index',inplace=True)
print(df)
reindex()函数
reindex()函数也是重命名函数,调用reindex方法后,会根据新索引进行重新排序,并按指定的索引返回对应的内容。
import pandas as pd #导入pandas库,取别名为pd
index = ['Firefox', 'Chrome', 'Safari', 'IE10', 'Konqueror']
df = pd.DataFrame({'http_status': [200,200,404,404,301],'response_time': [0.04, 0.02, 0.07, 0.08, 1.0]},index=index)
print(df)
new_index= ['Safari', 'Iceweasel', 'Comodo Dragon', 'IE10','Chrome']
df=df.reindex(new_index)
print(df)
其中,新标签中的Iceweasel和Comodo Dragon在原有标签中并不存在,所以它们所对应的数据部分是NaN空值。
重新排列列标签也是同样的,还可以指定fill_value参数填充空数据。并且以下两种方式等效:
import pandas as pd #导入pandas库,取别名为pd
index = ['Firefox', 'Chrome', 'Safari', 'IE10', 'Konqueror']
df = pd.DataFrame({'http_status': [200,200,404,404,301],'response_time': [0.04, 0.02, 0.07, 0.08, 1.0]},index=index)
print(df.reindex(columns=['http_status', 'user_agent'],fill_value=0))
print(df.reindex(['http_status', 'user_agent'], axis="columns",fill_value=0))
离散化和面元
离散化和面元划分
数据挖掘中有些算法,特别是分类算法,只能在离散型数据上进行分析,然而大部分数据集常常是连续值和离散值并存的。因此,为了使这类算法发挥作用,需要对数据集中连续型属性进行离散化操作。那么,如何对连续型属性离散化呢?常见的有等宽分箱法,等频分箱法。等宽分箱法的思想是,将数据均匀划分成n等份,每份的间距相等。等频分箱法的思想是,将观察点均匀分成n等份,每份的观察点数相同。
cut()函数
pandas.cut(x, bins, right=True, labels=None, retbins=False,precision=3,include_lowest=False)
x:要分箱的输入数组。它必须是一维的。
bin:int或标量序列。如果bins是一个int,它定义在x范围内的等宽单元的数量。然而,在这种情况下,x的范围在每一侧延伸0.1%以包括x的最小值或最大值。如果bin是一个序列,它定义了允许非均匀bin宽度的bin边缘。在这种情况下不进行x的范围的扩展。
right:bool,可选。决定区间的开闭,如果right == True(默认),则区间[1,2,3,4]指示(1,2],(2,3],(3,4]。
labels:array或boolean,默认值为无。用作生成的区间的标签。必须与生成的区间的长度相同。如果为False,则只返回bin的整数指示符。
retbins:bool,可选是否返回bin。如果bin作为标量给出,则可能有用。
precision:int,存储和显示容器标签的精度。
include_lowest:bool,第一个间隔是否应该包含左边。
qcut()函数
pandas.qcut(x, q, labels=None, retbins=False, precision=3)
x:ndarray或Series。
q:整数或分位数阵列分位数。十分位数为10,四分位数为4或者,分位数阵列,例如[0,.25,.5,.75,1.]四分位数
labels:array或boolean,默认值为无,用作生成的区间的标签。必须与生成的区间的长度相同。如果为False,则只返回bin的整数指示符。
retbins:bool,可选。是否返回bin。如果bin作为标量给出,则可能有用。
precision:int,存储和显示容器标签的精度。
使用cut()函数进行离散化数据
有一个由数字组成的一维数组,区间在[a,b]之中,那么使用cut()函数我们就可以平均分割这个区间,把数据中的数字划分到各个区间中:
import pandas as pd #导入pandas库,取别名为pd
import numpy as np #导入numpy库,取别名为np
pd=pd.cut(np.array([1, 7, 5, 4, 6, 3,11,65,99,35]), 3)
print(pd)
我们会发现命名数据是从1开始的,而结果中确实0.902这样一个比一小那么一点的数。这是因为cut()函数的right参数默认是True,表示区间仅右侧为闭区间,也就是左侧是开区间。所以为了使数据中的数字全部可以用区间表示,使得最小值向左偏移了最大值的0.1%大小。
如果想要使左区间也是闭区间,那么我们可以设置right参数为False:
import pandas as pd #导入pandas库,取别名为pd
import numpy as np #导入numpy库,取别名为np
pd=pd.cut(np.array([1, 7, 5, 4, 6, 3,11,65,99,35]), 3,right=False) #指定right参数
print(pd)
也可以给区间命名,比如低区间里的数据叫是bad,中间区间是medium,高区间是good。所以这时我们要指定labels参数:
import pandas as pd #导入pandas库,取别名为pd
import numpy as np #导入numpy库,取别名为np
pd=pd.cut(np.array([1, 7, 5, 4, 6, 3,11,65,99,35]), 3,labels=['bad','medium','good'])
print(pd)
还可以将Series作为输入传递返回具有分类dtype的Series:
import pandas as pd #导入pandas库,取别名为pd
import numpy as np #导入numpy库,取别名为np
s=pd.Series(np.array([2, 4, 6, 8, 10]),index=['a', 'b', 'c', 'd', 'e'])
pd=pd.cut(s, 3)
print(pd)
使用qcut()函数进行面元划分
在使用cut()函数的过程中我们知道cut()函数将根据值本身来选择箱子均匀间隔,而接下来要讲的qcut()函数则是根据这些值的频率来选择箱子的均匀间隔。
import pandas as pd
data = [1,5,65,9,8,5,3,78,59,6,23,6,45,12,54,6,7]
cats = pd.qcut(data, 4) # 按四分位数进行切割
print(cats)
print(pd.value_counts(cats))
通过指定分位数(0到1之间的数值,包含端点)进行面元划分:
import pandas as pd
# qcut可以根据样本分位数对数据进行面元划分
# data = np.random.randn(20) # 正态分布
data = [1,5,65,9,8,5,3,78,59,6,23,6,45,12,54,6,7]
cats = pd.qcut(data, 4) # 按四分位数进行切割
cats_2 = pd.qcut(data, [0, 0.5, 0.8, 0.9, 1])# 通过指定分位数(0到1之间的数值,包含端点)进行面元划分
print(cats_2)
print(pd.value_counts(cats_2))
利用函数或映射进行数据变换
在数据分析过程中,我们往往将数据集(Series和DataFrame类型的)的每一列看作是一个特征或变量,然后进行求取一些统计量,进行的操作也分为元素级的和数据集的列。
在python中有一个匿名函数lambda,匿名函数顾名思义就是指:是指一类无需定义标识符(函数名)的函数或子程序。
- lambda只是一个表达式,函数体比def简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda表达式是起到一个函数速写的作用。允许在代码内嵌入一个函数的定义。
实战训练:
导入pandas库,写入一个食物数据集,以及重量数据集(以盎司为单位):
import pandas as pd
data=pd.DataFrame({'food':['bacon','pulled pork','bacon','Pastrami','corned beef','Bacon','pastrami','honey ham','nova lox'],
'ounces':[4,3,12,6,7.5,8,3,5,6]})
print(data)
假如想添加一列表示该肉类食物来源的动物类型,我们先编写一个肉类到动物的映射:
meat_to_animal = {
'bacon':'pig',
'pulled pork':'pig',
'pastrami':'cow',
'corned beef':'cow',
'honey ham':'pig',
'nova lox':'salmon'
}
print(meat_to_animal)
Series的map方法可以接受一个函数或含有映射关系的字典型对象,但是这里有个问题:有些大写了,有些没有。因此需要先转换大小写,我们使用如下命令进行映射:
data['animal'] = data['food'].map(str.lower).map(meat_to_animal)
print(data)
map用来执行函数,即将data[‘food’]的每个元素应用到隐含函数:
print(data['food'].map(lambda x:meat_to_animal[x.lower()]))
print(data)
本次内容到此结束啦,感谢观看!!!