Pandas是Python语言的一个扩展程序库,用于数据分析。
Pandas是一个开放源码、BSD许可的库,提供高性能、易于使用的数据结构和数据分析工具。
Pandas名字衍生自术语 "panel data"(面板数据)和 "Python data analysis"(Python数据分析)。
Pandas一个强大的分析结构化数据的工具集,基础是NumPy(提供高性能的矩阵运算)。
Pandas可以从各种文件格式比如CSV、JSON、SQL、Microsoft Excel 导入数据。
Pandas可以对各种数据进行运算操作,比如归并、再成形、选择,还有数据清洗和数据加工特征。
Pandas广泛应用在学术、金融、统计学等各个数据分析领域。
Pandas主要包括以下几个特点:
它提供了一个简单、高效、带有默认标签(也可以自定义标签)的DataFrame对象。
能够快速从不同格式的文件中加载数据(比如 Excel、CSV 、SQL文件),然后转换为可处理的对象;
能够按数据的行、列标签进行分组,并对分组后的对象执行聚合和转换操作;
能够很方便地实现数据归一化操作和缺失值处理;
能够很方便地对DataFrame的数据列进行增加、修改或者删除的操作;
能够处理不同格式的数据集,比如矩阵数据、异构数据表、时间序列等;
提供了多种处理数据集的方式,比如构建子集、切片、过滤、分组以及重新排序等。
⛄Pandas数据结构
Pandas的主要数据结构是Series(一维数据)与DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。
Series 是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共同用一个索引)。
⛄Pandas Series
Pandas Series类似表格中的一个列(column),类似于一维数组,由一组数据值(value)和一组标签组成,其中标签与数据值之间是一一对应的关系。Series可以保存任何数据类型,比如整数、字符串、浮点数、Python对象等,它的标签默认为整数,从0开始依次递增。
👀创建Series对象
Series由索引(index)和列组成,函数如下:
pandas.Series(data, index, dtype, name, copy) 参数说明: data:一组数据(ndarray类型)。 index:数据索引标签,如果不指定,默认从0 开始。 dtype:数据类型,默认会自己判断。 name:设置名称。 copy:拷贝数据,默认为False 。 import pandas as pda = [1 , 2 , 3 ] myvar = pd.Series(a) print (myvar)print (myvar[1 ])0 1 1 2 2 3 dtype: int64 2
我们也可以使用数组、字典、标量值或者Python对象来创建Series对象。
(1)创建一个空Series对象
import pandas as pds = pd.Series() print (s)Series([], dtype: float64)
(2)ndarray创建Series对象
ndarray是NumPy中的数组类型,当data是ndarry时,传递的索引必须具有与数组相同的长度。如果没有指定索引(隐式索引),索引值就从0开始(索引值将使用是range(n) 生成,其中n代表数组长度);我们可以根据索引值读取数据。可以指定索引值(显式索引),如下实例。
import pandas as pdimport numpy as npa = np.array(["Google" , "Runoob" , "Wiki" ]) myvar = pd.Series(a, index = ["x" , "y" , "z" ]) print (myvar)print (myvar["y" ])x Google y Runoob z Wiki dtype: object Runoob
(3)dict创建Series对象
我们也可以使用key/value对象,类似字典来创建Series:
import pandas as pdsites = {1 : "Google" , 2 : "Runoob" , 3 : "Wiki" } myvar1 = pd.Series(sites) print (myvar1)myvar2 = pd.Series(sites, index = [1 ,2 ]) print (myvar2)myvar3 = pd.Series(sites, index = [1 ,3 ,2 ,4 ]) print (myvar3)1 Google2 Runoob3 Wikidtype: object 1 Google2 Runoobdtype: object 1 Google3 Wiki2 Runoob4 NaNdtype: object
当传递的索引值无法找到与其对应的值时,使用NaN(非数字)填充。
(4)标量创建Series对象
如果data是标量值,则必须提供索引,示例如下:
import pandas as pds = pd.Series(5 , index = [0 ,1 ,2 ,3 ]) print (s)0 5 1 5 2 5 3 5 dtype: int64
标量值按照index的数量进行重复,并与其一一对应。
设置Series名称参数:
import pandas as pdsites = {1 : "Google" , 2 : "Runoob" , 3 : "Wiki" } myvar = pd.Series(sites, index = [1 , 2 ], name="RUNOOB-Series-TEST" ) print (myvar)1 Google2 RunoobName: RUNOOB-Series-TEST, dtype: object
👀访问Series数据
(1)位置索引访问
这种访问方式与ndarray和list相同,使用元素自身的下标进行访问。我们知道数组的索引计数从0开始,这表示第一个元素存储在第0个索引位置上,以此类推,就可以获得Series序列中的每个元素。
import pandas as pds = pd.Series([5 ,2 ,3 ,4 ,5 ],index = ['a' ,'b' ,'c' ,'d' ,'e' ]) print (s[0 ]) print (s['a' ]) print (s[:3 ])print (s[-3 :])5 5 a 5 b 2 c 3 dtype: int64 c 3 d 4 e 5 dtype: int64
(2)索引标签访问
Series类似于固定大小的dict,把index中的索引标签当做key,而把Series序列中的元素值当做value,然后通过index索引标签来访问或者修改元素值。
import pandas as pds = pd.Series([16 ,17 ,18 ,19 ,20 ],index = ['a' ,'b' ,'c' ,'d' ,'e' ]) print (s['a' ])print (s[['a' ,'c' ,'d' ]])print (s['f' ])16 a 16 c 18 d 19 dtype: int64 ...... KeyError: 'f'
👀Series常用属性
Series的常用属性和方法:
axes
以列表的形式返回所有行索引标签
dtype
返回对象的数据类型
empty
返回一个空的Series对象
ndim
返回输入数据的维数
size
返回输入数据的元素数量
values
以ndarray的形式返回Series对象
index
返回一个RangeIndex对象,用来描述索引的取值范围
import pandas as pdimport numpy as nps = pd.Series(np.random.randn(6 )) print (s)print ("*" *20 )print (s.axes)print ("*" *20 )print (s.dtype)print ("*" *20 )print (s.empty)print ("*" *20 )print (s.ndim)print ("*" *20 )print (s.size)print ("*" *20 )print (s.values)print ("*" *20 )s1 = pd.Series([1 ,2 ,5 ,8 ],index = ['a' ,'b' ,'c' ,'d' ]) print (s1.index)s2 = pd.Series([1 ,2 ,5 ,8 ]) print (s2.index)0 -0.674501 1 1.030106 2 -1.636359 3 -1.540996 4 1.312837 5 -0.735986 dtype: float64 ******************** [RangeIndex(start=0 , stop=6 , step=1 )] ******************** float64 ******************** False ******************** 1 ******************** 6 ******************** [-0.67450078 1.03010573 -1.63635856 -1.54099596 1.31283698 -0.73598645 ] ******************** Index(['a' , 'b' , 'c' , 'd' ], dtype='object' ) RangeIndex(start=0 , stop=4 , step=1 )
👀Series常用方法
(1)head()&tail()查看数据
如果想要查看Series的某一部分数据,可以使用head()或者tail()方法。其中head()返回前n行数据,默认显示前5行数据。tail()返回的是后n行数据,默认为后5行。
import pandas as pdimport numpy as nps = pd.Series(np.random.randn(5 )) print (s)print (s.head(3 ))print (s.tail(3 ))0 -0.264915 1 -1.120671 2 0.621638 3 -0.449170 4 0.533876 dtype: float64 0 -0.264915 1 -1.120671 2 0.621638 dtype: float64 2 0.621638 3 -0.449170 4 0.533876 dtype: float64
(2)isnull()¬null()检测缺失值
isnull()和notnull()用于检测Series中的缺失值。所谓缺失值,顾名思义就是值不存在、丢失、缺少。
isnull():如果为值不存在或者缺失,则返回True。
notnull():如果值不存在或者缺失,则返回False。
其实不难理解,在实际的数据分析任物中,数据的收集往往要经历一个繁琐的过程。在这个过程中难免会因为一些不可抗力,或者人为因素导致数据丢失的现象。这时,我们可以使用相应的方法对缺失值进行处理,比如均值插值、数据补齐等方法。上述两个方法就是帮助我们检测是否存在缺失值。
import pandas as pds = pd.Series([1 ,6 ,None ,8 ,None ]) print (pd.isnull(s)) print (pd.notnull(s)) 0 False 1 False 2 True 3 False 4 True dtype: bool 0 True 1 True 2 False 3 True 4 False dtype: bool
⛄Pandas DataFrame
DataFrame是表格型的数据结构,既有行标签(index),又有列标签(columns),它也被称异构数据表。
它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame既有行索引 也有列索引 ,它可以被看做由Series组成的字典(共同用一个索引),每一行数据都可以看成一个Series结构,DataFrame为这些行中每个数据值增加了一个列标签。
同Series一样,DataFrame自带行标签索引,默认为“隐式索引”即从0开始依次递增,行标签与DataFrame中的数据项一一对应。DataFrame数据结构的特点:
DataFrame每一列的标签值允许使用不同的数据类型;
DataFrame是表格型的数据结构,具有行和列;
DataFrame中的每个数据值都可以被修改;
DataFrame结构的行数、列数允许增加或者删除;
DataFrame有两个方向的标签轴,分别是行标签和列标签;
DataFrame可以对行和列执行算术运算。
👀创建DF对象
DataFrame构造方法如下:
pandas.DataFrame(data, index, columns, dtype, copy) 参数说明: data:一组数据(ndarray、series, map , lists, dict 等类型)。 index:索引值,或者可以称为行标签。 columns:列标签,默认为RangeIndex(0 , 1 , 2 , …, n) 。 dtype:数据类型。 copy:拷贝数据,默认为False 。
Pandas DataFrame是一个二维的数组结构,类似二维数组。
Pandas提供了多种创建DataFrame对象的方式,主要包含以下五种:
(1)创建空的DataFrame对象
import pandas as pddf = pd.DataFrame() print (df)Empty DataFrame Columns: [] Index: []
(2)列表创建DataFame对象
可以使用单一列表或嵌套列表来创建一个DataFrame。
import pandas as pddata1 = [6 ,7 ,8 ,9 ,10 ] df1 = pd.DataFrame(data1) print (df1)data2 = [['Google' ,10 ],['Runoob' ,12 ],['Wiki' ,13 ]] df2 = pd.DataFrame(data2,columns = ['Site' ,'Age' ],dtype = float ) print (df2) 0 0 6 1 7 2 8 3 9 4 10 Site Age 0 Google 10.0 1 Runoob 12.0 2 Wiki 13.0
(3)字典嵌套列表创建DataFame对象
dict字典中,键对应的值的元素长度必须相同(也就是列表长度相同)。如果传递了索引,那么索引的长度应该等于数组的长度;如果没有传递索引,那么默认情况下,索引将是range(n),其中n代表数组长度。
import pandas as pddata = {'Site' :['Google' , 'Runoob' , 'Wiki' ], 'Age' :[10 , 12 , 13 ]} df = pd.DataFrame(data) print (df)df2 = pd.DataFrame(data,index = ['one' ,'two' ,'three' ]) print (df2) Site Age 0 Google 10 1 Runoob 12 2 Wiki 13 Site Age one Google 10 two Runoob 12 three Wiki 13
从以上输出结果可以知道, DataFrame数据类型一个表格,包含rows(行)和columns(列)。
(4)列表嵌套字典创建DataFrame对象
列表嵌套字典可以作为输入数据传递给DataFrame构造函数。默认情况下,字典的键被用作列名。
import pandas as pddata1 = [{'a' : 1 , 'b' : 2 }, {'a' : 5 , 'b' : 10 , 'c' : 20 }] data2 = {'a' :[1 , 5 ], 'b' :[2 , 10 ], 'c' :[15 , 20 ]} df1 = pd.DataFrame(data1) print (df1)df2 = pd.DataFrame(data2) print (df2)df3 = pd.DataFrame(data1,index = ['one' ,'two' ]) print (df3)df4 = pd.DataFrame(data1,index = ['one' ,'two' ],columns = ['a' ,'abc' ]) print (df4) a b c 0 1 2 NaN1 5 10 20.0 a b c 0 1 2 15 1 5 10 20 a b c one 1 2 NaN two 5 10 20.0 a abc one 1 NaN two 5 NaN
(5)Series创建DataFrame对象
可以传递一个字典形式的Series,从而创建一个DataFrame对象,其输出结果的行索引是所有index的合集。
import pandas as pdd = {'one' : pd.Series([1 , 2 , 3 ], index = ['a' , 'b' , 'c' ]), 'two' : pd.Series([1 , 2 , 3 , 4 ], index = ['a' , 'b' , 'c' , 'd' ])} df = pd.DataFrame(d) print (df) one two a 1.0 1 b 2.0 2 c 3.0 3 d NaN 4
👀列索引操作DF对象
DataFrame可以使用列索(columns index)引来完成数据的选取、添加和删除操作。
(1)列索引选取数据列
import pandas as pddata = { "calories" : [420 , 380 , 390 ], "duration" : [50 , 40 , 45 ] } df = pd.DataFrame(data, index = ['a' , 'b' , 'c' ]) print (df)print (df['calories' ]) calories duration a 420 50 b 380 40 c 390 45 a 420 b 380 c 390 Name: calories, dtype: int64
(2)列索引添加数据列
使用columns列索引表标签可以实现添加新的数据列。
import pandas as pddata = { "calories" : [420 , 380 , 390 ], "duration" : [50 , 40 , 45 ] } df = pd.DataFrame(data, index = ['a' , 'b' , 'c' ]) print (df)print ("*" *20 )df['height' ] = pd.Series([160 ,170 ,180 ], index = ['a' , 'b' , 'c' ]) print (df)print ("*" *20 )df['sums' ] = df['calories' ] + df['duration' ] print (df) calories duration a 420 50 b 380 40 c 390 45 ******************** calories duration height a 420 50 160 b 380 40 170 c 390 45 180 ******************** calories duration height sums a 420 50 160 470 b 380 40 170 420 c 390 45 180 435
我们初次使用了DataFrame的算术运算,这和NumPy非常相似。除了使用df[]=value的方式外,您还可以使用insert()方法插入新的列.
import pandas as pdinfo = [['Jack' ,18 ],['Helen' ,19 ],['John' ,17 ]] df = pd.DataFrame(info,columns = ['name' ,'age' ]) print (df)df.insert(1 ,column = 'score' ,value = [91 ,90 ,75 ]) print (df) name age 0 Jack 18 1 Helen 19 2 John 17 name score age 0 Jack 91 18 1 Helen 90 19 2 John 75 17
(3)列索引删除数据列
通过del和pop()都能够删除DataFrame中的数据列。示例如下:
import pandas as pdd = {'one' : pd.Series([1 , 2 , 3 ], index = ['a' , 'b' , 'c' ]), 'two' : pd.Series([1 , 2 , 3 , 4 ], index = ['a' , 'b' , 'c' , 'd' ]), 'three' : pd.Series([10 ,20 ,30 ], index = ['a' ,'b' ,'c' ])} df = pd.DataFrame(d) print (df)print ("*" *20 )del df['one' ]print (df)print ("*" *20 )df.pop('two' ) print (df) one two three a 1.0 1 10.0 b 2.0 2 20.0 c 3.0 3 30.0 d NaN 4 NaN ******************** two three a 1 10.0 b 2 20.0 c 3 30.0 d 4 NaN ******************** three a 10.0 b 20.0 c 30.0 d NaN
👀行索引操作DF对象
Pandas可以使用loc函数返回指定行的数据,如果没有设置索引,第一行索引为0,第二行索引为1,以此类推。
(1)标签索引选取
通过将行标签传递给loc函数,来选取数据。
loc允许接两个参数分别是行和列,参数之间需要使用“逗号”隔开,但该函数只能接收标签索引 。
import pandas as pddata = { "calories" : [420 , 380 , 390 ], "duration" : [50 , 40 , 45 ] } df = pd.DataFrame(data, index = ['a' , 'b' , 'c' ]) print (df)print ('*' *20 )print (df.loc['a' ]) calories duration a 420 50 b 380 40 c 390 45 ******************** calories 420 duration 50 Name: a, dtype: int64
(2)整数索引选取
通过将数据行所在的索引位置传递给iloc函数,也可以实现数据行选取。
iloc允许接受两个参数分别是行和列,参数之间使用“逗号”隔开,但该函数只能接收整数索引 。
import pandas as pddata = { "calories" : [420 , 380 , 390 ], "duration" : [50 , 40 , 45 ] } df = pd.DataFrame(data, index = ['a' , 'b' , 'c' ]) print (df)print ('*' *20 )print (df.iloc[0 ])print ('*' *20 )print (df.iloc[1 ])print ('*' *20 )print (df.iloc[[0 , 1 ]]) calories duration a 420 50 b 380 40 c 390 45 ******************** calories 420 duration 50 Name: a, dtype: int64 ******************** calories 380 duration 40 Name: b, dtype: int64 ******************** calories duration a 420 50 b 380 40
(3)切片操作多行数据
通过使用切片的方式同时选取多行。
import pandas as pddata = { "calories" : [420 , 380 , 390 ], "duration" : [50 , 40 , 45 ] } df = pd.DataFrame(data, index = ['a' , 'b' , 'c' ]) print (df)print ('*' *20 )print (df[1 :3 ]) calories duration a 420 50 b 380 40 c 390 45 ******************** calories duration b 380 40 c 390 45
(4)添加数据行
使用append()函数,可以将新的数据行添加到DataFrame中,该函数会在行末追加数据行。
import pandas as pddf = pd.DataFrame([[1 , 2 ], [3 , 4 ]], index = ['one' ,'two' ], columns = ['a' ,'b' ]) df2 = pd.DataFrame([[5 , 6 ], [7 , 8 ]], index = ['one' ,'two' ], columns = ['a' ,'b' ]) df = df.append(df2) print (df) a b one 1 2 two 3 4 one 5 6 two 7 8
(5)删除数据行
使用行索引标签,从DataFrame中删除某一行数据。如果索引标签存在重复,那么它们将被一起删除。
import pandas as pddf = pd.DataFrame([[1 , 2 ], [3 , 4 ]], index = ['one' ,'two' ], columns = ['a' ,'b' ]) df2 = pd.DataFrame([[5 , 6 ], [7 , 8 ]], index = ['one' ,'two' ], columns = ['a' ,'b' ]) df = df.append(df2) print (df)print ('*' *20 )df1 = df.drop('one' ) print (df1) a b one 1 2 two 3 4 one 5 6 two 7 8 ******************** a b two 3 4 two 7 8
👀DF对象属性和方法
DataFrame的属性和方法,与Series相差无几。
T
行和列转置
axes
返回一个仅以行轴标签和列轴标签为成员的列表
dtypes
返回每列数据的数据类型
empty
DataFrame中没有数据或者任意坐标轴的长度为0,则返回True
ndim
轴的数量,也指数组的维数。
shape
返回一个元组,表示了DataFrame维度
size
DataFrame中的元素数量
values
使用numpy数组表示DataFrame中的元素值
head()
返回前n行数据
tail()
返回后n行数据
shift()
将行或列移动指定的步幅长度
import pandas as pdimport numpy as npd = {'Name' :pd.Series(['小汤' ,'小王' ,"小明" ,'小红' ,'小小' ,'小微' ,'小黄' ]), 'years' :pd.Series([2005 ,2006 ,2015 ,2008 ,2003 ,2009 ,2003 ]), 'height' :pd.Series([180 ,175 ,178 ,179 ,176 ,170 ,173 ])} df = pd.DataFrame(d) print (df)print ('*' *20 )print (df.T)print ('*' *20 )print (df.axes)print ('*' *20 )print (df.dtypes)print ('*' *20 )print (df.empty)print ('*' *20 )print (df.ndim)print ('*' *20 )print (df.shape)print ('*' *20 )print (df.size)print ('*' *20 )print (df.values)print ('*' *20 ) Name years height 0 小汤 2005 180 1 小王 2006 175 2 小明 2015 178 3 小红 2008 179 4 小小 2003 176 5 小微 2009 170 6 小黄 2003 173 ******************** 0 1 2 3 4 5 6 Name 小汤 小王 小明 小红 小小 小微 小黄 years 2005 2006 2015 2008 2003 2009 2003 height 180 175 178 179 176 170 173 ******************** [RangeIndex(start=0 , stop=7 , step=1 ), Index(['Name' , 'years' , 'height' ], dtype='object' )] ******************** Name object years int64 height int64 dtype: object ******************** False ******************** 2 ******************** (7 , 3 ) ******************** 21 ******************** [['小汤' 2005 180 ] ['小王' 2006 175 ] ['小明' 2015 178 ] ['小红' 2008 179 ] ['小小' 2003 176 ] ['小微' 2009 170 ] ['小黄' 2003 173 ]] ********************
head()&tail()查看数据。如果想要查看DataFrame的一部分数据,可以使用head()或者tail()方法。head()返回前n行数据,默认显示前5行数据。tail()返回后n行数据。
import pandas as pdimport numpy as npd = {'Name' :pd.Series(['小汤' ,'小王' ,"小明" ,'小红' ,'小小' ,'小微' ,'小黄' ]), 'years' :pd.Series([2005 ,2006 ,2015 ,2008 ,2003 ,2009 ,2003 ]), 'height' :pd.Series([180 ,175 ,178 ,179 ,176 ,170 ,173 ])} df = pd.DataFrame(d) print (df)print ('*' *20 )print (df.head(3 ))print ('*' *20 )print (df.tail(2 )) Name years height 0 小汤 2005 180 1 小王 2006 175 2 小明 2015 178 3 小红 2008 179 4 小小 2003 176 5 小微 2009 170 6 小黄 2003 173 ******************** Name years height 0 小汤 2005 180 1 小王 2006 175 2 小明 2015 178 ******************** Name years height 5 小微 2009 170 6 小黄 2003 173
shift()移动行或列。如果您想要移动DataFrame中的某一行/列,可以使用shift()函数实现。它提供了一个periods参数,该参数表示在特定的轴上移动指定的步幅。
DataFrame.shift(periods=1 , freq=None , axis=0 ) 参数说明: peroids 类型为int ,表示移动的幅度,可以是正数,也可以是负数,默认值为1 。 freq 日期偏移量,默认值为None ,适用于时间序。取值为符合时间规则的字符串。 axis 如果是0 或者"index" 表示上下移动,如果是1 或者"columns" 则会左右移动。 fill_value 该参数用来填充缺失值。
import pandas as pdimport numpy as npd = {'Name' :pd.Series(['小汤' ,'小王' ,"小明" ,'小红' ,'小小' ,'小微' ,'小黄' ]), 'years' :pd.Series([2005 ,2006 ,2015 ,2008 ,2003 ,2009 ,2003 ]), 'height' :pd.Series([180 ,175 ,178 ,179 ,176 ,170 ,173 ])} df = pd.DataFrame(d) print (df)print ('*' *20 )print (df.shift(periods=3 ))print ('*' *20 )print (df.shift(periods=3 ,fill_value=52 )) print ('*' *20 )print (df.shift(periods=3 ,axis=1 ,fill_value=52 )) Name years height 0 小汤 2005 180 1 小王 2006 175 2 小明 2015 178 3 小红 2008 179 4 小小 2003 176 5 小微 2009 170 6 小黄 2003 173 ******************** Name years height 0 NaN NaN NaN1 NaN NaN NaN2 NaN NaN NaN3 小汤 2005.0 180.0 4 小王 2006.0 175.0 5 小明 2015.0 178.0 6 小红 2008.0 179.0 ******************** Name years height 0 52 52 52 1 52 52 52 2 52 52 52 3 小汤 2005 180 4 小王 2006 175 5 小明 2015 178 6 小红 2008 179 ******************** Name years height 0 52 52 52 1 52 52 52 2 52 52 52 3 52 52 52 4 52 52 52 5 52 52 52 6 52 52 52
⛄Pandas函数操作
👀Panel结构(了解)
Panel是一个用来承载数据的三维数据结构,它有三个轴,分别是items(0轴),major_axis(1轴),而 minor_axis(2轴)。这三个轴为描述、操作Panel提供了支持,其作用介绍如下:
items:axis =0,Panel 中的每个items都对应一个DataFrame。
major_axis:axis=1,用来描述每个DataFrame的行索引。
minor_axis:axis=2,用来描述每个DataFrame的列索引。
pandas.Panel(data, items, major_axis, minor_axis, dtype, copy) 参数说明: data 输入数据,可以是 ndarray,Series,列表,字典,或者 DataFrame。 items axis=0 major_axis axis=1 minor_axis axis=2 dtype 每一列的数据类型。 copy 默认为 False ,表示是否复制数据。
自Pandas 0.25版本后, Panel结构已经被废弃。
👀描述性统计函数
count()
统计某个非空值的数量
sum()
求和
mean()
求均值
median()
求中位数
mode()
求众数
std()
求标准差
min()
求最小值
max()
求最大值
abs()
求绝对值
prod()
求所有数值的乘积
cumsum()
计算累计和,axis=0,按照行累加;axis=1,按照列累加
cumprod()
计算累计积,axis=0,按照行累积;axis=1,按照列累积
corr()
计算数列或变量之间的相关系数,取值-1到1,值越大表示关联性越强
describe()
显示与DataFrame数据列相关的统计信息摘要
在DataFrame中,使用聚合类方法时需要指定轴(axis)参数。下面介绍两种传参方式:
对行操作,默认使用axis=0或者使用 "index";
对列操作,默认使用axis=1或者使用 "columns"。
axis=0表示按垂直方向进行计算,而axis=1则表示按水平方向。
describe()函数输出了平均值、std和IQR值(四分位距)等一系列统计信息。通过describe()提供的include能够筛选字符列或者数字列的摘要信息。include相关参数值说明如下:
object: 表示对字符列进行统计信息描述;
number:表示对数字列进行统计信息描述;
all:汇总所有列的统计信息。
import pandas as pdimport numpy as npd = {'Name' :pd.Series(['小汤' ,'小王' ,"小明" ,'小红' ,'小小' ,'小微' ,'小黄' ]), 'years' :pd.Series([2005 ,2006 ,2015 ,2008 ,2003 ,2009 ,2003 ]), 'height' :pd.Series([180 ,175 ,178 ,179 ,176 ,170 ,173 ])} df = pd.DataFrame(d) print (df)print ('*' *20 )print (df.describe())print ('*' *20 )print (df.describe(include=["object" ]))print ('*' *20 )print (df.describe(include="all" )) Name years height 0 小汤 2005 180 1 小王 2006 175 2 小明 2015 178 3 小红 2008 179 4 小小 2003 176 5 小微 2009 170 6 小黄 2003 173 ******************** years height count 7.000000 7.000000 mean 2007.000000 175.857143 std 4.203173 3.532165 min 2003.000000 170.000000 25 % 2004.000000 174.000000 50 % 2006.000000 176.000000 75 % 2008.500000 178.500000 max 2015.000000 180.000000 ******************** Name count 7 unique 7 top 小汤 freq 1 ******************** Name years height count 7 7.000000 7.000000 unique 7 NaN NaN top 小汤 NaN NaN freq 1 NaN NaN mean NaN 2007.000000 175.857143 std NaN 4.203173 3.532165 min NaN 2003.000000 170.000000 25 % NaN 2004.000000 174.000000 50 % NaN 2006.000000 176.000000 75 % NaN 2008.500000 178.500000 max NaN 2015.000000 180.000000
👀自定义函数
如果想要应用自定义的函数,或者把其他库中的函数应用到Pandas对象中,有以下三种方法:
操作整个DataFrame的函数:pipe()
操作行或者列的函数:apply()
操作单一元素的函数:applymap()
(1)操作整个数据表
通过给pipe()函数传递一个自定义函数和适当数量的参数值,从而操作DataFrme中的所有元素。下面示例,实现了数据表中的元素值依次加 6。
import pandas as pdimport numpy as npdef addsum (a1,a2 ): return a1 + a2 df = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print (df.pipe(addsum,6 )) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 c1 c2 c3 0 126 136 156 1 96 106 116 2 66 76 86
(2)操作行或列
如果要操作DataFrame的某一行或者某一列,可以使用apply()方法,该方法与描述性统计方法类似,都有可选参数axis,并且默认按列操作。示例如下:
import pandas as pdimport numpy as npdf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )print (df.apply(np.mean))print ('*' *20 )print (df.apply(np.mean,axis=1 ))print ('*' *20 )print (df.apply(lambda x: x.max () - x.min ())) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** c1 90.000000 c2 100.000000 c3 113.333333 dtype: float64 ******************** 0 133.333333 1 100.000000 2 70.000000 dtype: float64 ******************** c1 60 c2 60 c3 70 dtype: int64
(3)操作单一元素
DataFrame数据表结构的applymap()和Series系列结构的map()类似,它们都可以接受一个Python函数,并返回相应的值。
import pandas as pddf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )print (df['c1' ].map (lambda x:x*10 ))print ('*' *20 )print (df.applymap(lambda x:x*10 )) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** 0 1200 1 900 2 600 Name: c1, dtype: int64 ******************** c1 c2 c3 0 1200 1300 1500 1 900 1000 1100 2 600 700 800
👀reindex重置索引
重置索引(reindex)可以更改原DataFrame的行标签或列标签,并使更改后的行、列标签与DataFrame中的数据逐一匹配。通过重置索引操作,您可以完成对现有数据的重新排序。如果重置的索引标签在原DataFrame中不存在,那么该标签对应的元素值将全部填充为NaN。
(1)重置行列标签
import pandas as pddf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )df_reindexed = df.reindex(index=[0 ,1 ], columns=['c1' , 'c3' ]) print (df_reindexed) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** c1 c3 0 120 150 1 90 110
现有a、b两个DataFrame对象,如果想让a的行索引与b相同,您可以使用reindex_like() 方法。示例如下:
import pandas as pdimport numpy as npa = pd.DataFrame(np.random.randn(10 ,3 ),columns=['col1' ,'col2' ,'col3' ]) b = pd.DataFrame(np.random.randn(7 ,3 ),columns=['col1' ,'col2' ,'col3' ]) a= a.reindex_like(b) print (a) col1 col2 col3 0 0.669617 0.010243 -0.091776 1 -0.333395 -1.521432 0.292087 2 -0.174709 -0.623413 1.291384 3 1.033132 -0.383137 1.280788 4 1.052466 -1.326848 -1.390581 5 1.828058 0.422678 -0.734622 6 0.988210 -1.047092 -1.959839
(2)填充元素值
reindex_like()提供了一个可选的参数method,使用它来填充相应的元素值,参数值介绍如下:
pad/ffill:向前填充值;
bfill/backfill:向后填充值;
nearest:从距离最近的索引值开始填充。
reindex_like()还提供了一个额外参数limit,该参数用来控制填充的最大行数。示例如下:
import pandas as pdimport numpy as npdf1 = pd.DataFrame(np.random.randn(6 ,3 ),columns=['col1' ,'col2' ,'col3' ]) df2 = pd.DataFrame(np.random.randn(2 ,3 ),columns=['col1' ,'col2' ,'col3' ]) print (df2.reindex_like(df1))print ('*' *20 )print (df2.reindex_like(df1,method='ffill' ))print ('*' *20 )print (df2.reindex_like(df1,method='backfill' ))print ('*' *20 )print (df2.reindex_like(df1,method='ffill' ,limit=2 )) col1 col2 col3 0 0.552991 1.230408 0.403586 1 -0.135228 1.065911 -0.624843 2 NaN NaN NaN3 NaN NaN NaN4 NaN NaN NaN5 NaN NaN NaN******************** col1 col2 col3 0 0.552991 1.230408 0.403586 1 -0.135228 1.065911 -0.624843 2 -0.135228 1.065911 -0.624843 3 -0.135228 1.065911 -0.624843 4 -0.135228 1.065911 -0.624843 5 -0.135228 1.065911 -0.624843 ******************** col1 col2 col3 0 0.552991 1.230408 0.403586 1 -0.135228 1.065911 -0.624843 2 NaN NaN NaN3 NaN NaN NaN4 NaN NaN NaN5 NaN NaN NaN******************** col1 col2 col3 0 0.552991 1.230408 0.403586 1 -0.135228 1.065911 -0.624843 2 -0.135228 1.065911 -0.624843 3 -0.135228 1.065911 -0.624843 4 NaN NaN NaN5 NaN NaN NaN
(3)重命名标签
rename()方法允许您使用某些映射(dict或Series)或任意函数来对行、列标签重新命名,示例如下:
import pandas as pddf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )print (df.rename(columns={'c1' :'cc1' ,'c2' :'cc2' },index = {0 :'one' ,1 :'two' ,2 :'three' })) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** cc1 cc2 c3 one 120 130 150 two 90 100 110 three 60 70 80
rename()方法提供了一个inplace参数,默认值为False,表示拷贝一份原数据,并在复制后的数据上做重命名操作。若inplace=True则表示在原数据的基础上重命名。
👀iteration遍历操作
Pandas是如何遍历Series和DataFrame结构呢?对于Series而言,您可以把它当做一维数组进行遍历操作;而像DataFrame这种二维数据表结构,则类似于遍历Python字典。
在Pandas中同样也是使用for循环进行遍历。通过for遍历后,Series可直接获取相应的value,而DataFrame则会获取列标签。示例如下:
import pandas as pddf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )for col in df: print (col) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** c1 c2 c3
如果想要遍历DataFrame的每一行,我们下列函数:
iteritems():以键值对 (key,value) 的形式遍历;
iterrows():以 (row_index,row) 的形式遍历行;
itertuples():使用已命名元组的方式对行遍历。
iteritems()以键值对的形式遍历DataFrame对象,以列标签 为键,以对应列的元素为值。
import pandas as pddf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )for key,value in df.iteritems(): print (key) print (value) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** c1 0 120 1 90 2 60 Name: c1, dtype: int64 c2 0 130 1 100 2 70 Name: c2, dtype: int64 c3 0 150 1 110 2 80 Name: c3, dtype: int64
iterrows()方法按行遍历,返回一个迭代器,以行索引 标签为键,以每一行数据为值。
import pandas as pddf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )for row_index,value in df.iterrows(): print (row_index) print (value) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** 0 c1 120 c2 130 c3 150 Name: 0 , dtype: int64 1 c1 90 c2 100 c3 110 Name: 1 , dtype: int64 2 c1 60 c2 70 c3 80 Name: 2 , dtype: int64
itertuples()同样将返回一个迭代器,该方法会把DataFrame的每一行 生成一个元组,示例如下:
import pandas as pddf = pd.DataFrame([[120 ,130 ,150 ],[90 ,100 ,110 ],[60 ,70 ,80 ]],columns=['c1' ,'c2' ,'c3' ]) print (df)print ('*' *20 )for row in df.itertuples(): print (row) c1 c2 c3 0 120 130 150 1 90 100 110 2 60 70 80 ******************** Pandas(Index=0 , c1=120 , c2=130 , c3=150 ) Pandas(Index=1 , c1=90 , c2=100 , c3=110 ) Pandas(Index=2 , c1=60 , c2=70 , c3=80 )
迭代器返回的是原对象的副本,如果在迭代过程中修改元素值,不会影响原对象。
👀排序和去重
👁排序sorting
Pandas提供了两种排序方法,分别是按标签排序和按数值排序。
(1)按行标签排序
使用sort_index()方法对行标签排序 ,指定轴参数(axis)或者排序顺序。或者可以对DataFrame进行排序。默认情况下,按照行标签序排序。通过将布尔值传递给ascending参数,可以控制排序的顺序(行号顺序)。
import pandas as pdimport numpy as npunsorted_df = pd.DataFrame(np.random.randn(6 ,2 ),index=[1 ,4 ,2 ,3 ,5 ,0 ],columns=['col2' ,'col1' ]) print (unsorted_df)print ('*' *20 )sorted_df1 = unsorted_df.sort_index() print (sorted_df1)print ('*' *20 )sorted_df2 = unsorted_df.sort_index(ascending=False ) print (sorted_df2) col2 col1 1 -0.458463 0.422606 4 0.809682 2.489952 2 1.609935 0.096181 3 1.087255 1.215676 5 0.436520 0.389565 0 0.536720 0.820746 ******************** col2 col1 0 0.536720 0.820746 1 -0.458463 0.422606 2 1.609935 0.096181 3 1.087255 1.215676 4 0.809682 2.489952 5 0.436520 0.389565 ******************** col2 col1 5 0.436520 0.389565 4 0.809682 2.489952 3 1.087255 1.215676 2 1.609935 0.096181 1 -0.458463 0.422606 0 0.536720 0.820746
(2)按列标签排序
通过给axis轴参数传递0或1,可以对列标签进行排序。默认情况下,axis=0表示按行排序;而axis=1则表示按列排序。
import pandas as pdimport numpy as npunsorted_df = pd.DataFrame(np.random.randn(6 ,2 ),index=[1 ,4 ,2 ,3 ,5 ,0 ],columns=['col2' ,'col1' ]) print (unsorted_df)print ('*' *20 )sorted_df1 = unsorted_df.sort_index(axis=1 ) print (sorted_df1) col2 col1 1 0.891755 1.006258 4 0.232999 0.549146 2 0.158894 0.246825 3 0.653124 -1.695749 5 -0.774252 -0.525881 0 0.082147 0.384929 ******************** col1 col2 1 1.006258 0.891755 4 0.549146 0.232999 2 0.246825 0.158894 3 -1.695749 0.653124 5 -0.525881 -0.774252 0 0.384929 0.082147
(3)按值排序
与标签排序类似,sort_values()表示按值排序。它接受一个by参数,该参数值是要排序数列的DataFrame列名。示例如下:
import pandas as pdunsorted_df = pd.DataFrame({'col1' :[2 ,1 ,1 ,1 ],'col2' :[1 ,3 ,2 ,4 ]}) print (unsorted_df)print ('*' *20 )sorted_df1 = unsorted_df.sort_values(by='col1' ) print (sorted_df1)print ('*' *20 )sorted_df2 = unsorted_df.sort_values(by=['col1' ,'col2' ]) print (sorted_df2) col1 col2 0 2 1 1 1 3 2 1 2 3 1 4 ******************** col1 col2 1 1 3 2 1 2 3 1 4 0 2 1 ******************** col1 col2 2 1 2 1 1 3 3 1 4 0 2 1
(4)排序算法
sort_values()提供了参数kind用来指定排序算法。这里有三种排序算法:
mergesort
heapsort
quicksort
默认为quicksort(快速排序) ,其中Mergesort归并排序是最稳定的算法。
import pandas as pdunsorted_df = pd.DataFrame({'col1' :[2 ,1 ,1 ,1 ],'col2' :[1 ,3 ,2 ,4 ]}) print (unsorted_df)print ('*' *20 )sorted_df1 = unsorted_df.sort_values(by='col1' ,kind='mergesort' ) print (sorted_df1) col1 col2 0 2 1 1 1 3 2 1 2 3 1 4 ******************** col1 col2 1 1 3 2 1 2 3 1 4 0 2 1
👁去重drop_duplicates()
“去重”通过字面意思不难理解,就是删除重复的数据。在一个数据集中,找出重复的数据删并将其删除,最终只保存一个唯一存在的数据项,这就是数据去重的整个过程。
Panda DataFrame对象提供了一个数据去重的函数drop_duplicates()
df.drop_duplicates(subset=['A' ,'B' ,'C' ],keep='first' ,inplace=True ) 参数说明如下: subset:表示要进去重的列名,默认为None 。 keep:有三个可选参数,分别是first、last、False ,默认为first,表示只保留第一次出现的重复项,删除其余重复项,last表示只保留最后一次出现的重复项,False 则表示删除所有重复项。 inplace:布尔值参数,默认为False 表示删除重复项后返回一个副本,若为Ture则表示直接在原数据上删除重复项。
删除重复项后,行标签使用的数字是原来的,并没有从0重新开始,那么我们应该怎么从0重置索引呢?Pandas提供的reset_index()函数会直接使用重置后的索引。
import pandas as pddata = {'col1' :[1 ,0 ,1 ,1 ],'col2' :[0 ,2 ,5 ,0 ],'col3' :[4 ,0 ,4 ,4 ],'col4' :[1 ,0 ,1 ,1 ]} df = pd.DataFrame(data) print (df)print ('*' *20 )print (df.drop_duplicates())print ('*' *20 )df1 = df.drop_duplicates(keep=False ) print (df1)print ('*' *20 )print (df1.reset_index(drop=True ))print ('*' *20 )print (df.drop_duplicates(['col3' ,'col4' ],keep='last' )) col1 col2 col3 col4 0 1 0 4 1 1 0 2 0 0 2 1 5 4 1 3 1 0 4 1 ******************** col1 col2 col3 col4 0 1 0 4 1 1 0 2 0 0 2 1 5 4 1 ******************** col1 col2 col3 col4 1 0 2 0 0 2 1 5 4 1 ******************** col1 col2 col3 col4 0 0 2 0 0 1 1 5 4 1 ******************** col1 col2 col3 col4 1 0 2 0 0 3 1 0 4 1
👀字符串处理
Pandas提供了一系列的字符串函数,因此能够很方便地对字符串进行处理。
lower()
将的字符串转换为小写
upper()
将的字符串转换为大写
len()
得出字符串的长度
strip()
去除字符串两边的空格(包含换行符)
split()
用指定的分割符分割字符串
cat(sep="")
用给定的分隔符连接字符串元素
get_dummies()
返回一个带有独热编码值的DataFrame结构
contains(pattern)
如果子字符串包含在元素中,则为每个元素返回一个布尔值True,否则为False
replace(a,b)
将值a替换为值b
count(pattern)
返回每个字符串元素出现的次数
startswith(pattern)
如果Series中的元素以指定的字符串开头,则返回True
endswith(pattern)
如果Series中的元素以指定的字符串结尾,则返回True
findall(pattern)
以列表的形式返出现的字符串
swapcase()
交换大小写
islower()
返回布尔值,检查Series中组成每个字符串的所有字符是否都为小写
issupper()
返回布尔值,检查Series中组成每个字符串的所有字符是否都为大写
isnumeric()
返回布尔值,检查Series中组成每个字符串的所有字符是否都为数字
repeat(value)
以指定的次数重复每个元素
find(pattern)
返回字符串第一次出现的索引位置
注意:上述所有字符串函数全部适用于DataFrame对象,同时也可以与Python内置的字符串函数一起使用,这些函数在处理Series/DataFrame对象的时候会自动忽略缺失值数据(NaN)。
import pandas as pdimport numpy as nps = pd.Series(['C ' , ' Python' , 'java' , 'go' , np.nan, '1125 ' ,'javascript' ]) print (s.str .lower)print ('*' *20 )print (s.str .len ())print ('*' *20 )print (s.str .strip())print ('*' *20 )print (s.str .split(" " ))print ('*' *20 )print (s.str .cat(sep="_" ))print ('*' *20 )print (s.str .get_dummies())print ('*' *20 )print (s.str .contains(" " ))print ('*' *20 )print (s.str .repeat(3 ))print ('*' *20 )print (s.str .startswith("j" ))print ('*' *20 )print (s.str .find("j" ))print ('*' *20 )print (s.str .swapcase())print ('*' *20 )print (s.str .isnumeric())0 c 1 python2 java3 go4 NaN5 1125 6 javascriptdtype: object ******************** 0 2.0 1 7.0 2 4.0 3 2.0 4 NaN5 5.0 6 10.0 dtype: float64 ******************** 0 C1 Python2 java3 go4 NaN5 1125 6 javascriptdtype: object ******************** 0 [C, ]1 [, Python]2 [java]3 [go]4 NaN5 [1125 , ]6 [javascript]dtype: object ******************** C _ Python_java_go_1125 _javascript ******************** Python 1125 C go java javascript 0 0 0 1 0 0 0 1 1 0 0 0 0 0 2 0 0 0 0 1 0 3 0 0 0 1 0 0 4 0 0 0 0 0 0 5 0 1 0 0 0 0 6 0 0 0 0 0 1 ******************** 0 True 1 True 2 False 3 False 4 NaN5 True 6 False dtype: object ******************** 0 C C C 1 Python Python Python2 javajavajava3 gogogo4 NaN5 1125 1125 1125 6 javascriptjavascriptjavascriptdtype: object ******************** 0 False 1 False 2 True 3 False 4 NaN5 False 6 True dtype: object ******************** 0 -1.0 1 -1.0 2 0.0 3 -1.0 4 NaN5 -1.0 6 0.0 dtype: float64 ******************** 0 c 1 pYTHON2 JAVA3 GO4 NaN5 1125 6 JAVASCRIPTdtype: object ******************** 0 False 1 False 2 False 3 False 4 NaN5 False 6 False dtype: object
👀设置数据显示格式
在用Pandas做数据分析的过程中,总需要打印数据分析的结果,如果数据体量较大就会存在输出内容不全(部分内容省略)或者换行错误等问题。Pandas为了解决上述问题,允许你对数据显示格式进行设置。下面列出了五个用来设置显示格式的函数,分别是:
get_option()
获取解释器的默认参数值
set_option()
更改解释器的默认参数值
reset_option()
解释器的参数重置为默认值
describe_option()
输出参数的描述信息
option_context()
临时设置解释器参数,当退出使用的语句块时,恢复为默认值
上述函数常用的参数项:
display.max_rows
最大显示行数,超过该值用省略号代替,为None时显示所有行
display.max_columns
最大显示列数,超过该值用省略号代替,为None时显示所有列
display.expand_frame_repr
输出数据宽度超过设置宽度时,表示是否对其要折叠,False不折叠,True要折叠
display.max_colwidth
单列数据宽度,以字符个数计算,超过时用省略号表示
display.precision
设置输出数据的小数点位数
display.width
数据显示区域的宽度,以总字符数计算
display.show_dimensions
当数据量大需要以truncate(带引号的省略方式)显示时,该参数表示是否在最后显示数据的维数,默认True显示,False不显示。
👀loc和iloc用法详解
在数据分析过程中,很多时候需要从数据表中提取出相应的数据,而这么做的前提是需要先“索引”出这一部分数据。虽然通过Python提供的索引操作符"[]"和属性操作符"."可以访问Series或者DataFrame中的数据,但这种方式只适应与少量的数据,为了解决这一问题,Pandas提供了两种类型的索引方式来实现数据的访问。
.loc[]
基于标签索引选取数据
.iloc[]
基于整数索引选取数据
df.loc[]只能使用标签索引,不能使用整数索引。当通过标签索引的切片方式来筛选数据时,它的取值前闭后闭,也就是只包括边界值标签(开始和结束)。
.loc[]具有多种访问方法,如下所示:
loc[]接受两个参数,并以','分隔。第一个位置表示行,第二个位置表示列。
import pandas as pddata = { "name" : ['Tom' , 'Rose' , 'Mike' , 'Twg' ], "calories" : [420 , 380 , 390 , 500 ], "duration" : [50 , 40 , 45 , 60 ] } df = pd.DataFrame(data, index = ['a' , 'b' , 'c' , 'd' ]) print (df)print ('*' *20 )print (df.loc['a' :'b' ,:])print ('*' *20 )print (df.loc[:,'name' ])print ('*' *20 )print (df.loc[['a' ,'d' ],['name' ,'duration' ]])print ('*' *20 )print (df.loc[:,'duration' ] > 45 ) name calories duration a Tom 420 50 b Rose 380 40 c Mike 390 45 d Twg 500 60 ******************** name calories duration a Tom 420 50 b Rose 380 40 ******************** a Tom b Rose c Mike d Twg Name: name, dtype: object ******************** name duration a Tom 50 d Twg 60 ******************** a True b False c False d True Name: duration, dtype: bool
df.iloc[]只能使用整数索引,不能使用标签索引,通过整数索引切片选择数据时,前闭后开(不包含边界结束值)。同Python和NumPy一样,它们的索引都是从0开始。
.iloc[]提供了以下方式来选择数据:
import pandas as pddata = { "name" : ['Tom' , 'Rose' , 'Mike' , 'Twg' ], "calories" : [420 , 380 , 390 , 500 ], "duration" : [50 , 40 , 45 , 60 ] } df = pd.DataFrame(data, index = ['a' , 'b' , 'c' , 'd' ]) print (df)print ('*' *20 )print (df.iloc[2 :,:])print ('*' *20 )print (df.iloc[[0 ,2 ],[1 ,2 ]])print ('*' *20 )print (df.iloc[:,:2 ]) name calories duration a Tom 420 50 b Rose 380 40 c Mike 390 45 d Twg 500 60 ******************** name calories duration c Mike 390 45 d Twg 500 60 ******************** calories duration a 420 50 c 390 45 ******************** name calories a Tom 420 b Rose 380 c Mike 390 d Twg 500
👀日期时间操作
👁Pandas时间序列
顾名思义,时间序列(time series),就是由时间构成的序列,它指的是在一定时间内按照时间顺序测量的某个变量的取值序列,比如一天内的温度会随时间而发生变化,或者股票的价格会随着时间不断的波动,这里用到的一系列时间,就可以看做时间序列。时间序列包含三种应用场景,分别是:
特定的时刻(timestamp),也就是时间戳;
固定的日期(period),比如某年某月某日;
时间间隔(interval),每隔一段时间具有规律性;
在处理时间序列的过程中,我们一般会遇到两个问题,第一,如何创建时间序列;第二,如何更改已生成时间序列的频率。 Pandas为解决上述问题提供了一套简单、易用的方法。
from datetime import datetimeprint (datetime.now())2023 -03-19 17 :42 :39.528176
创建时间戳:TimeStamp(时间戳) 是时间序列中的最基本的数据类型,它将数值与时间点完美结合在一起。
创建时间间隔:通过date_range()方法可以创建某段连续的时间或者固定间隔的时间时间段。该函数提供了三个参数,分别是:start开始时间;end结束时间;freq时间频率,默认为 "D"(天)。
import pandas as pdprint (pd.Timestamp('2023-03-16' ))print (pd.Timestamp(1687687255 ,unit='s' ))print ('*' *20 )print (pd.date_range("9:00" , "18:10" , freq="30min" ).time)print (pd.date_range("9:00" , "18:10" , freq="H" ).time)print ('*' *20 )print (pd.to_datetime(pd.Series(['Jun 3, 2020' ,'2020-12-10' , None ])))print (pd.to_datetime(['Jun 30, 2020' ,'2020-12-10' , None ]))2023 -03-16 00 :00 :00 2023 -06-25 10 :00 :55 ******************** [datetime.time(9 , 0 ) datetime.time(9 , 30 ) datetime.time(10 , 0 ) datetime.time(10 , 30 ) datetime.time(11 , 0 ) datetime.time(11 , 30 ) datetime.time(12 , 0 ) datetime.time(12 , 30 ) datetime.time(13 , 0 ) datetime.time(13 , 30 ) datetime.time(14 , 0 ) datetime.time(14 , 30 ) datetime.time(15 , 0 ) datetime.time(15 , 30 ) datetime.time(16 , 0 ) datetime.time(16 , 30 ) datetime.time(17 , 0 ) datetime.time(17 , 30 ) datetime.time(18 , 0 )] [datetime.time(9 , 0 ) datetime.time(10 , 0 ) datetime.time(11 , 0 ) datetime.time(12 , 0 ) datetime.time(13 , 0 ) datetime.time(14 , 0 ) datetime.time(15 , 0 ) datetime.time(16 , 0 ) datetime.time(17 , 0 ) datetime.time(18 , 0 )] ******************** 0 2020 -06-031 2020 -12 -10 2 NaTdtype: datetime64[ns] DatetimeIndex(['2020-06-30' , '2020-12-10' , 'NaT' ], dtype='datetime64[ns]' , freq=None )
频率和周期转换:Time Periods表示时间跨度,一段时间周期,它被定义在Pandas Periods类中,通过该类提供的方法可以实现将频率转换为周期。比如Periods()方法,可以将频率 "M"(月)转换为 Period(时间段)。使用asfreq()和start参数,打印 "01" ,若使用end参数,则打印 "31"。对于常用的时间序列频率,Pandas为其规定了一些字符串别名,我们将这些别名称为“offset(偏移量)”。
B
工作日频率
BQS
工作季度开始频率
D
日历日频率
A
年终频率
W
每周频率
BA
工作年度结束频率
M
月末频率
BAS
工作年度开始频率
SM
半月结束频率
BH
营业时间频率
BM
工作月结束频率
H
小时频率
MS
月开始频率
T,min
每分钟频率
SMS
半月开始频率
S
每秒钟频率
BMS
工作月开始频率
L,ms
毫秒
Q
季末频率
U,us
微秒
BQ
工作季度结束频率
N
纳秒
QS
季度开始频率
周期计算:指的是对时间周期进行算术运算,所有的操作将在“频率”的基础上执行。
创建时间周期:可以使用period_range()方法来创建时间周期范围。
时间序列转换:如果想要把字符串日期转换为Period,首先需要将字符串转换为日期格式,然后再将日期转换为Period。
import pandas as pd x = pd.Period('2014' , freq='S' ) print (x)print (x+1 )p = pd.period_range('2016' ,'2018' , freq='Y' ) print (p)2014 -01-01 00 :00 :00 2014 -01-01 00 :00 :01PeriodIndex(['2016' , '2017' , '2018' ], dtype='period[A-DEC]' , freq='A-DEC' )
👁日期时间格式化
当进行数据分析时,我们会遇到很多带有日期、时间格式的数据集,在处理这些数据集时,可能会遇到日期格式不统一的问题,此时就需要对日期时间做统一的格式化处理。比如"Wednesday, June 6, 2020"可以写成"6/6/20",或者写成"06-06-2020"。
(1)日期格式化符号
在对时间进行格式化处理时,它们都有固定的表示格式,比如小时的格式化符号为%H ,分钟简写为%M ,秒简写为%S。
%y
两位数的年份表示(00-99)
%Y
四位数的年份表示(000-9999)
%m
月份(01-12)
%d
月内中的一天(0-31)
%H
24小时制小时数(0-23)
%I
12小时制小时数(01-12)
%M
分钟数(00=59)
%S
秒(00-59)
%a
本地英文缩写星期名称
%A
本地英文完整星期名称
%b
本地缩写英文的月份名称
%B
本地完整英文的月份名称
%w
星期(0-6),星期天为星期的开始
%W
一年中的星期数(00-53)星期一为星期的开始
%x
本地相应的日期表示
%X
本地相应的时间表示
%Z
当前时区的名称
%U
一年中的星期数(00-53)星期天为星期的开始
%j
年内的一天(001-366)
%c
本地相应的日期表示和时间表示
(2)日期格式化处理函数
Python内置的strptime()方法能够将字符串日期转换为datetime类型。
from datetime import datetimedate_str1 = 'Wednesday,July 18,2020' date_str2 = '18/7/20' date_str3 = '18-07-2020' dmy_dt1 = datetime.strptime(date_str1, '%A,%B %d,%Y' ) dmy_dt2 = datetime.strptime(date_str2, '%d/%m/%y' ) dmy_dt3 = datetime.strptime(date_str3, '%d-%m-%Y' ) print (dmy_dt1) print (dmy_dt2) print (dmy_dt3) 2020 -07-18 00 :00 :00 2020 -07-18 00 :00 :00 2020 -07-18 00 :00 :00
除了使用Python内置的strptime()方法外,你还可以使用Pandas模块的pd.to_datetime()和pd.DatetimeIndex()进行转换。
import pandas as pdimport numpy as npdate1 = ['2012-05-06 11:00:00' ,'2012-05-16 11:00:00' ] pd_date1 = pd.to_datetime(date1) df1 = pd.Series(np.random.randn(2 ),index=pd_date1) print (pd_date1)print (df1)print ('*' *20 )date2 = pd.DatetimeIndex(['1/1/2008' , '1/2/2008' , '1/3/2008' , '1/4/2008' , '1/5/2008' ]) dt2 = pd.DataFrame(np.random.randn(5 ),index=date2, columns=['value' ]) print (date2)print (dt2)DatetimeIndex(['2012-05-06 11:00:00' , '2012-05-16 11:00:00' ], dtype='datetime64[ns]' , freq=None ) 2012 -05-06 11 :00 :00 2.115566 2012 -05-16 11 :00 :00 -0.145139 dtype: float64 ******************** DatetimeIndex(['2008-01-01' , '2008-01-02' , '2008-01-03' , '2008-01-04' , '2008-01-05' ], dtype='datetime64[ns]' , freq=None ) value 2008 -01-01 0.828022 2008 -01-02 -1.873516 2008 -01-03 1.940921 2008 -01-04 1.563612 2008 -01-05 0.964914
👁Timedelta时间差
Timedelta表示时间差(或者时间增量),我们可以使用不同的时间单位来表示它,比如,天、小时、分、秒。时间差的最终的结果可以是正时间差,也可以是负时间差。
import pandas as pdimport numpy as npprint (pd.Timedelta('5 days 8 hours 6 minutes 59 seconds' ))print (pd.Timedelta(19 ,unit='h' ))print (pd.Timedelta(days=2 ,hours=6 ))print ('*' *20 )print (pd.to_timedelta(['1 days 06:05:01.00003' , '15.5us' , 'nan' ]))print (pd.to_timedelta(np.arange(5 ), unit='s' ))5 days 08:06:59 0 days 19 :00 :00 2 days 06:00 :00 ******************** TimedeltaIndex(['1 days 06:05:01.000030' , '0 days 00:00:00.000015' , NaT], dtype='timedelta64[ns]' , freq=None ) TimedeltaIndex(['00:00:00' , '00:00:01' , '00:00:02' , '00:00:03' , '00:00:04' ], dtype='timedelta64[ns]' , freq=None )
通过对datetime64[ns]类型的时间序列或时间戳做算术运算,其运算结果依然是datetime64[ns]数据类型。接下来,我们创建一个带有Timedelta与datetime的DataFrame对象,并对其做一些算术运算。
import pandas as pds = pd.Series(pd.date_range('2020-1-1' , periods=5 , freq='D' )) td = pd.Series([ pd.Timedelta(days=i) for i in range (5 )]) df = pd.DataFrame(dict (A = s, B = td)) print (df)print ('*' *20 )df['C' ]=df['A' ]+df['B' ] print (df)print ('*' *20 )df['D' ]=df['C' ]-df['B' ] print (df) A B 0 2020 -01-01 0 days1 2020 -01-02 1 days2 2020 -01-03 2 days3 2020 -01-04 3 days4 2020 -01-05 4 days******************** A B C 0 2020 -01-01 0 days 2020 -01-011 2020 -01-02 1 days 2020 -01-032 2020 -01-03 2 days 2020 -01-053 2020 -01-04 3 days 2020 -01-074 2020 -01-05 4 days 2020 -01-09******************** A B C D 0 2020 -01-01 0 days 2020 -01-01 2020 -01-011 2020 -01-02 1 days 2020 -01-03 2020 -01-022 2020 -01-03 2 days 2020 -01-05 2020 -01-033 2020 -01-04 3 days 2020 -01-07 2020 -01-044 2020 -01-05 4 days 2020 -01-09 2020 -01-05
👀数据样本处理
👁Pandas缺失值处理
稀疏数据,指的是在数据库或者数据集中存在大量缺失数据或者空值,我们把这样的数据集称为稀疏数据集。稀疏数据不是无效数据,只不过是信息不全而已,只要通过适当的方法就可以“变废为宝”。
检查缺失值 :Pandas提供了isnull()和notnull()两个函数,它们同时适用于Series和DataFrame对象。
缺失数据计算 :计算缺失数据时,需要注意两点:首先数据求和时,将NA值视为0,其次,如果要计算的数据为NA,那么结果就是NA。
清理并填充缺失值 :Pandas提供了多种方法来清除缺失值。fillna()函数可以实现用非空数据“填充”NaN值;ffill()向前填充和bfill()向后填充,使用这两个函数也可以处理NA值。replace()将DataFrame中的通用值替换成特定值。
删除缺失值 :使用dropna()函数与参数axis可以实现删除缺失值。在默认情况下,按照axis=0来按行处理,这意味着如果某一行中存在NaN值将会删除整行数据。
👁Pandas随机样本选择
随机抽样,是统计学中常用的一种方法,它可以帮助我们从大量的数据中快速地构建出一组数据分析模型。在Pandas中,如果想要对数据集进行随机抽样,需要使用sample()函数。该函数返回与数据集类型相同的新对象,相当于numpy.random.choice()。
DataFrame.sample(n=None ,frac=None ,replace=False ,weights=None ,random_state=None ,axis=None ) 参数说明 n 表示要抽取的行数。 frac 表示抽取的比例,比如frac=0.5 ,代表抽取总体数据的50 %。 replace 布尔值参数,表示是否以有放回抽样的方式进行选择,默认为False ,取出数据后不再放回。 weights 可选参数,代表每个样本的权重值,参数值是字符串或者数组。 random_state 可选参数,控制随机状态,默认为None ,表示随机数据不会重复;若为1 表示会取得重复数据。 axis 表示在哪个方向上抽取数据(axis=1 表示列/axis=0 表示行)。
👁Pandas数据重采样
数据重采样是将时间序列从一个频率转换至另一个频率的过程,它主要有两种实现方式,分别是降采样和升采样,降采样指将高频率的数据转换为低频率,升采样则与其恰好相反,说明如下:
降采样
将高频率(间隔短)数据转换为低频率(间隔长)。
升采样
将低频率数据转换为高频率。
Pandas提供了resample()函数来实现数据的重采样。
asfreq()方法不仅能够实现频率转换,还可以保留原频率对应的数值,同时它也可以单独使用。
插值处理,升采样的结果会产生缺失值,那么就需要对缺失值进行处理,一般有以下几种处理方式:
pad/ffill
用前一个非缺失值去填充缺失值。
backfill/bfill
用后一个非缺失值去填充缺失值。
interpolater('linear')
线性插值方法。
fillna(value)
指定一个值去替换缺失值。
👁Pandas分类对象
通常情况下,数据集中会存在许多同一类别的信息,比如相同国家、相同行政编码、相同性别等,当这些相同类别的数据多次出现时,就会给数据处理增添许多麻烦,导致数据集变得臃肿,不能直观、清晰地展示数据。
Pandas提供了分类对象(Categorical Object),该对象能够实现有序排列、自动去重的功能,但是它不能执行运算。通过Category的构造函数,您可以创建一个类别对象。
pandas.Categorical(values, categories, ordered) 参数说明 values:以列表的形式传参,表示要分类的值。 ordered:布尔值,默认为False ,若为Ture,表示对分类的数据进行排序。 dtype:返回一个category类型,表示分类对象。
describe():对已经分类的数据使用describe()方法,得到和数据统计相关的摘要信息。
categories:使用obj.categories命令可以获取对象的类别信息。
Series.cat.categories:对类别实现重命名。
Series.cat.add_categories():追加新类别。
Series.cat.remove_categories():删除不需要的类别。
👀其它函数
👁Pandas统计函数
Pandas的本质是统计学原理在计算机领域的一种应用实现,通过编程的方式达到分析、描述数据的目的。而统计函数则是统计学中用于计算和分析数据的一种工具。在数据分析的过程中,使用统计函数有助于我们理解和分析数据。常见的统计函数,比如百分比函数、协方差函数、相关系数等。
pct_change() :Series和DatFrames都可以使用pct_change()函数。该函数将每个元素与其前一个元素进行比较,并计算前后数值的百分比变化。默认情况下,pct_change()对列进行操作,如果想要操作行,则需要传递参数axis=1参数。
cov():Series对象提供了一个cov方法用来计算Series对象之间的协方差。同时,该方法也会将缺失值(NAN)自动排除。当应用于DataFrame时,协方差(cov)将计算所有列之间的协方差。
corr():相关系数显示任意两个Series之间的线性关系。Pandas提供了计算相关性的三种方法,分别是pearson(default)、spearman()和kendall()。注意:如果DataFrame存在非数值(NAN),该方法会自动将其删除。
rank() :按照某种规则(升序或者降序)对序列中的元素值排名,该函数的返回值的也是一个序列,包含了原序列中每个元素值的名次。如果序列中包含两个相同的的元素值,那么会为其分配两者的平均排名。
👁Pandas窗口函数
为了能更好地处理数值型数据,Pandas提供了几种窗口函数:
移动函数(rolling)
扩展函数(expanding)
指数加权函数(ewm)
窗口是一种形象化的叫法,这些函数在执行操作时,就如同窗口一样在数据区间上移动。
如何在DataFrame和Series对象上应用窗口函数:
rolling() :移动窗口函数,它可以与mean、count、sum、median、std等聚合函数一起使用。
rolling(window=n, min_periods=None , center=False ) 参数说明 window 默认值为1 ,表示窗口的大小,也就是观测值的数量, min_periods 表示窗口的最小观察值,默认与window的参数值相等。 center 是否把中间值做为窗口标准,默认值为False 。
expanding() :扩展窗口函数,扩展是指由序列的第一个元素开始,逐个向后计算元素的聚合值。
ewm():(全称 Exponentially Weighted Moving)表示指数加权移动。ewn()函数先会对序列元素做指数加权运算,其次计算加权后的均值。该函数通过指定com、span或者halflife参数来实现指数加权移动。
在数据分析的过程中,使用窗口函数能够提升数据的准确性,并且使数据曲线的变化趋势更加平滑,从而让数据分析变得更加准确、可靠。
👁Pandas聚合函数
窗口函数可以与聚合函数一起使用,聚合函数指的是对一组数据求总和、最大值、最小值以及平均值的操作,本节重点讲解聚合函数的应用。
import pandas as pdimport numpy as npdata = {'col1' :[1 ,0 ,1 ,1 ],'col2' :[0 ,2 ,5 ,0 ],'col3' :[4 ,0 ,4 ,4 ],'col4' :[1 ,0 ,1 ,1 ]} df = pd.DataFrame(data) print (df)print ("*" *20 )r1 = df.rolling(window=3 ,min_periods=1 ) r2 = df.rolling(window=3 ) print (r1.sum ())print (r2.sum ())print ("*" *20 )print (r1.aggregate(np.sum ))print ("*" *20 )print (r1['col1' ].aggregate(np.sum ))print ("*" *20 )print (r1['col1' ,'col2' ].aggregate(np.sum ))print ("*" *20 )print (r1['col1' ].aggregate([np.sum ,np.mean]))print ("*" *20 )print (r1['col1' ,'col2' ].aggregate([np.sum ,np.mean]))print ("*" *20 )print (r1.aggregate({'col1' :np.sum ,'col2' :np.mean})) col1 col2 col3 col4 0 1 0 4 1 1 0 2 0 0 2 1 5 4 1 3 1 0 4 1 ******************** col1 col2 col3 col4 0 1.0 0.0 4.0 1.0 1 1.0 2.0 4.0 1.0 2 2.0 7.0 8.0 2.0 3 2.0 7.0 8.0 2.0 col1 col2 col3 col4 0 NaN NaN NaN NaN1 NaN NaN NaN NaN2 2.0 7.0 8.0 2.0 3 2.0 7.0 8.0 2.0 ******************** col1 col2 col3 col4 0 1.0 0.0 4.0 1.0 1 1.0 2.0 4.0 1.0 2 2.0 7.0 8.0 2.0 3 2.0 7.0 8.0 2.0 ******************** 0 1.0 1 1.0 2 2.0 3 2.0 Name: col1, dtype: float64 ******************** col1 col2 0 1.0 0.0 1 1.0 2.0 2 2.0 7.0 3 2.0 7.0 ******************** sum mean 0 1.0 1.000000 1 1.0 0.500000 2 2.0 0.666667 3 2.0 0.666667 ******************** col1 col2 sum mean sum mean 0 1.0 1.000000 0.0 0.000000 1 1.0 0.500000 2.0 1.000000 2 2.0 0.666667 7.0 2.333333 3 2.0 0.666667 7.0 2.333333 ******************** col1 col2 0 1.0 0.000000 1 1.0 1.000000 2 2.0 2.333333 3 2.0 2.333333
👁groupby分组操作
在数据分析中,经常会遇到这样的情况:根据某一列(或多列)标签把数据划分为不同的组别,然后再对其进行数据分析。比如,某网站对注册用户的性别或者年龄等进行分组,从而研究出网站用户的画像(特点)。在Pandas 中,要完成数据的分组操作,需要使用groupby()函数,它和SQL的GROUP BY操作非常相似。 在划分出来的组(group)上应用一些统计函数,从而达到数据分析的目的,比如对分组数据进行聚合、转换,或者过滤。这个过程主要包含以下三步:
拆分(Spliting):表示对数据进行分组;
应用(Applying):对分组数据应用聚合函数,进行相应计算;
合并(Combining):最后汇总计算结果。
使用groupby()可以沿着任意轴分组。您可以把分组时指定的键(key)作为每组的组名,方法如下所示:
df.groupby("key")
df.groupby("key",axis=1)
df.groupby(["key1","key2"])
import pandas as pdimport numpy as npdata = {'name' : ['John' , 'Helen' , 'John' , 'Ella' ], 'score' : [82 , 98 , 91 , 87 ], 'option_course' : ['C#' ,'Python' ,'Java' ,'C' ]} df = pd.DataFrame(data) print (df)print ("*" *20 )print (df.groupby('score' ))print ("*" *20 )print (df.groupby('score' ).groups)print ("*" *20 )print (df.groupby(['name' ,'score' ]).groups)print ("*" *20 )print (df.groupby('score' ).get_group(91 ))print ("*" *20 )grouped=df.groupby('score' ) for label, option_course in grouped: print (label) print (option_course) print ("*" *20 )grouped_name = df.groupby('name' ) print (grouped_name['score' ].agg(np.mean)) print (grouped_name['score' ].agg([np.size,np.mean,np.std]))print ("*" *20 )print (grouped_name.filter (lambda x: len (x) >= 2 )) name score option_course 0 John 82 C1 Helen 98 Python2 John 91 Java3 Ella 87 C******************** <pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001CB3F4CD948 > ******************** {82 : Int64Index([0 ], dtype='int64' ), 87 : Int64Index([3 ], dtype='int64' ), 91 : Int64Index([2 ], dtype='int64' ), 98 : Int64Index([1 ], dtype='int64' )} ******************** {('Ella' , 87 ): Int64Index([3 ], dtype='int64' ), ('Helen' , 98 ): Int64Index([1 ], dtype='int64' ), ('John' , 82 ): Int64Index([0 ], dtype='int64' ), ('John' , 91 ): Int64Index([2 ], dtype='int64' )} ******************** name score option_course 2 John 91 Java******************** 82 name score option_course 0 John 82 C87 name score option_course 3 Ella 87 C91 name score option_course 2 John 91 Java98 name score option_course 1 Helen 98 Python******************** name Ella 87.0 Helen 98.0 John 86.5 Name: score, dtype: float64 size mean std name Ella 1 87.0 NaN Helen 1 98.0 NaN John 2 86.5 6.363961 ******************** name score option_course 0 John 82 C2 John 91 Java
组的转换操作:通过transform()函数可以实现组的转换,在组的行或列上可以执行转换操作,最终会返回一个与组大小相同的索引对象。
组的数据过滤操作:通过filter()函数可以实现数据的筛选,该函数根据定义的条件过滤数据并返回一个新的数据集。
👁merge合并操作
Pandas提供的merge()函数能够进行高效的合并操作,这与SQL关系型数据库的MERGE用法非常相似。从字面意思上不难理解,merge翻译为“合并”,指的是将两个DataFrame数据表按照指定的规则进行连接,最后拼接成一个新的DataFrame数据表。merge()函数的法格式如下:
pd.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 ) 参数说明 left/right: 两个不同的DataFrame对象。 on: 指定用于连接的键(即列标签的名字),该键必须同时存在于左右两个DataFrame中,如果没有指定,并且其他参数也未指定, 那么将会以两个DataFrame的列名交集做为连接键。 left_on: 指定左侧DataFrame中作连接键的列名。该参数在左、右列标签名不相同,但表达的含义相同时非常有用。 right_on: 指定左侧DataFrame中作连接键的列名。 left_index: 布尔参数,默认为False 。如果为True 则使用左侧DataFrame的行索引作为连接键,若DataFrame具有多层索引(MultiIndex),则层的数量必须与连接键的数量相等。 right_index: 布尔参数,默认为False 。如果为True 则使用左侧DataFrame的行索引作为连接键。 how: 要执行的合并类型,从{'left' ,'right' ,'outer' ,'inner' } 中取值,默认为“inner”内连接。 sort: 布尔值参数,默认为True ,它会将合并后的数据进行排序;若设置为False ,则按照how给定的参数值进行排序。 suffixes: 字符串组成的元组。当左右DataFrame存在相同列名时,通过该参数可以在相同的列名后附加后缀名,默认为('_x' ,'_y' )。 copy: 默认为True ,表示对数据进行复制。
注意:Pandas库的merge()支持各种内外连接,与其相似的还有join()函数(默认为左连接)。
👁concat连接操作
Pandas通过concat()函数能够轻松地将Series与DataFrame对象组合在一起,函数的语法格式如下:
pd.concat(objs, axis=0 , join='outer' , join_axes=None , ignore_index=False ) 参数说明 objs: 一个序列或者是Series、DataFrame对象。 axis: 表示在哪个轴方向上(行或者列)进行连接操作,默认axis=0 表示行方向。 join: 指定连接方式,取值为{"inner" ,"outer" },默认为outer表示取并集,inner代表取交集。 ignore_index: 布尔值参数,默认为False ,如果为True ,表示不在连接的轴上使用索引。 join_axes: 表示索引对象的列表。
append(): 如果要连接Series和DataFrame对象,有一个最方便、快捷的方法,就是append()方法。该方法沿着axis=0(行方向)进行操作;append()函数也可接收多个对象。
👀Pandas绘图
Pandas对Matplotlib绘图软件包的基础上单独封装了一个plot()接口,通过调用该接口可以实现常用的绘图操作。
import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.randn(8 ,4 ),index=pd.date_range('2/1/2020' ,periods=8 ), columns=list ('ABCD' )) df.plot()
除了使用默认的线条绘图外,您还可以使用其他绘图方式,如下所示:
柱状图:bar() 或 barh()
直方图:hist()
箱状箱:box()
区域图:area()
散点图:scatter()
通过关键字参数kind可以把上述方法传递给plot()。
(1)柱状图
import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.rand(10 ,4 ),columns=['a' ,'b' ,'c' ,'d' ]) df.plot.bar() df.plot(kind="bar" ,stacked=True ) df.plot.barh(stacked=True )
(2)直方图
plot.hist()可以实现绘制直方图,并且它还可以指定bins(构成直方图的箱数)。
import pandas as pdimport numpy as npdf = pd.DataFrame({'A' :np.random.randn(100 )+2 ,'B' :np.random.randn(100 ),'C' :np.random.randn(100 )-2 ,'D' :np.random.randn(100 )+3 },columns=['A' , 'B' , 'C' ,'D' ]) print (df)df.plot.hist(bins=15 ) df.diff().hist(color="r" ,alpha=0.5 ,bins=15 )
(3)箱线图
通过调用Series.box.plot() 、DataFrame.box.plot()或者DataFrame.boxplot()方法来绘制箱型图,它将每一列数据的分布情况,以可视化的图像展现出来。
import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.rand(10 , 4 ), columns=['A' , 'B' , 'C' , 'D' ]) df.plot.box()
(4)区域图
使用Series.plot.area()或DataFrame.plot.area()方法来绘制区域图。
import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.rand(5 , 4 ), columns=['a' , 'b' , 'c' , 'd' ]) df.plot.area()
(5)散点图
使用DataFrame.plot.scatter()方法来绘制散点图。
import pandas as pdimport numpy as npdf = pd.DataFrame(np.random.rand(30 , 4 ), columns=['a' , 'b' , 'c' , 'd' ]) df.plot.scatter(x='a' ,y='b' )
(6)饼状图
通过DataFrame.plot.pie()方法来绘制。
import pandas as pdimport numpy as npdf = pd.DataFrame(3 * np.random.rand(4 ), index=['go' , 'java' , 'c++' , 'c' ], columns=['L' ]) df.plot.pie(subplots=True )
⛄Pandas和NumPy的比较
Pandas和NumPy被认为是科学计算与机器学习中必不可少的库,因为它们具有直观的语法和高性能的矩阵计算能力。
适应性
Pandas主要用来处理类表格数据。
NumPy主要用来处理数值数据。
工具
Pandas提供了Series和DataFrame数据结构。
NumPy构建了ndarray array来容纳数据。
性能
Pandas对于处理50万行以上的数据更具优势。
NumPy则对于50万以下或者更少的数据,性能更佳。
内存利用率
与NumPy相比,Pandas会消耗大量的内存。
NumPy会消耗较少的内存。
对象
Pandas提供了DataFrame 2D数据表对象。
NumPy则提供了一个多维数组ndarray对象
在某些情况下,需要执行一些NumPy数值计算的高级函数,这个时候您可以使用to_numpy()函数,将DataFrame对象转换为NumPy ndarray数组,并将其返回。
DataFrame.to_numpy(dtype=None , copy=False ) 参数说明如下: dtype:可选参数,表示数据类型; copy:布尔值参数,默认值为 Fales,表示返回值不是其他数组的视图。 import pandas as pd info = pd.DataFrame([[17 ,62 ,35 ],[25 ,36 ,54 ],[42 ,20 ,15 ],[48 ,62 ,76 ]], columns=['x' ,'y' ,'z' ]) print ('DataFrame\n----------\n' , info) arr = info.to_numpy() print ('\nNumpy Array\n----------\n' , arr)DataFrame ---------- x y z 0 17 62 35 1 25 36 54 2 42 20 15 3 48 62 76 Numpy Array ---------- [[17 62 35 ] [25 36 54 ] [42 20 15 ] [48 62 76 ]]