数据分析工具Pandas
数据分析工具Pandas
01 Pandas的数据结构分析
Series
Pandas的Series类对象可以使用以下构造方法创建:
class pandas.Series(data = None,index = None,dtype = None,
name = None,copy = False,fastpath = False)
注释:
data:表示传入的数据。
index:表示索引,唯一且与数据长度相等,默认会自动创建一个从0~N的整数索引。
# 创建Series类对象
ser_obj = pd.Series([1, 2, 3, 4, 5])
# 创建Series类对象,并指定索引
ser_obj = pd.Series([1, 2, 3, 4, 5],
index=['a', 'b', 'c', 'd', 'e'])
除了使用列表构建Series类对象外,还可以使用dict进行构建。
year_data = {2001: 17.8, 2002: 20.1, 2003: 16.5}
ser_obj2 = pd.Series(year_data)
为了能方便地操作Series对象中的索引和数据,所以该对象提供了两个属性index和values分别进行获取
#获取ser_obj的索引
ser_obj.index
#获取ser_obj的数据
ser_obj.values
DataFrame
注:DataFrame是一个类似于二维数组或表格(如excel)的对象,它每列的数据可以是不同的数据类型
Pandas的DataFrame类对象可以使用以下构造方法创建:
pandas.DataFrame(data = None,index = None,columns = None,
dtype = None,copy = False )
index:表示行标签。若不设置该参数,则默认会自动创建一个从0~N的整数索引。
columns:列标签。
# 创建数组
demo_arr = np.array([['a', 'b', 'c'],
['d', 'e', 'f']])
# 基于数组创建DataFrame对象
df_obj = pd.DataFrame(demo_arr)
#在创建DataFrame类对象时,如果为其指定了列索引,则DataFrame的列会按照指定索引的顺序进行排列。
df_obj = pd.DataFrame(demo_arr, columns=['No1', 'No2', 'No3'])
我们可以使用列索引的方式来获取一列数据,返回的结果是一个Series对象。
# 通过列索引的方式获取一列数据
element = df_obj['No2']
# 查看返回结果的类型
type(element)
要想为DataFrame增加一列数据,则可以通过给列索引或者列名称赋值的方式实现。
# 增加No4一列数据
df_obj['No4'] = ['g', 'h']
要想删除某一列数据,则可以使用del语句实现。
# 删除No3一列数据
del df_obj['No3']
02 Pandas索引操作及高级索引
索引对象
Pandas中的索引都是Index类对象,又称为索引对象,该对象是不可以进行修改的,以保障数据的安全。
Pandas还提供了很多Index的子类,常见的有如下几种:
(1)Int64Index:针对整数的特殊Index对象。
(2)MultiIndex:层次化索引,表示单个轴上的多层索引。
(3)DatetimeIndex:存储纳秒寄时间戳。
Pandas中提供了一个重要的方法是reindex(),该方法的作用是对原索引和新索引进行匹配,也就是说,新索引含有原索引的数据,而原索引数据按照新索引排序。
如果新索引中没有原索引数据,那么程序不仅不会报错,而且会添加新的索引,并将值填充为NaN或者使用fill_vlues()填充其他值。
DataFrame.reindex(labels = None,index = None,
columns = None,axis = None,method = None,
copy = True,level = None,fill_value = nan,limit = None,tolerance = None )
注释:
index:用作索引的新序列。
method:插值填充方式。
fill_value:引入缺失值时使用的替代值。
limit:前向或者后向填充时的最大填充量。
如果不想填充为NaN,则可以使用fill_value参数来指定缺失值。
ser_obj.reindex(['a', 'b', 'c', 'd', 'e', 'f'],
fill_value = 6)
如果期望使用相邻的元素值进行填充,则可以使用method参数,该参数对应的值有多个
Series有关索引的用法类似于NumPy数组的索引,只不过Series的索引值不只是整数。如果我们希望获取某个数据,既可以通过索引的位置来获取,也可以使用索引名称来获取。
ser_obj = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
ser_obj[2] # 使用索引位置获取数据
ser_obj['c'] # 使用索引名称获取数据
如果使用的是位置索引进行切片,则切片结果是不包含结束位置;如果使用索引名称进行切片,则切片结果是包含结束位置的。
ser_obj[2: 4] # 使用位置索引进行切片
ser_obj['c': 'e'] # 使用索引名称进行切片
如果希望获取的是不连续的数据,则可以通过不连续索引来实现。
# 通过不连续位置索引获取数据集
ser_obj[[0, 2, 4]]
# 通过不连续索引名称获取数据集
ser_obj[['a', 'c', 'd']]
布尔型索引同样适用于Pandas,具体的用法跟数组的用法一样,将布尔型的数组索引作为模板筛选数据,返回与模板中True位置对应的元素。
# 创建布尔型Series对象
ser_bool = ser_obj > 2
# 获取结果为True的数据ser_obj[ser_bool]
DataFrame结构既包含行索引,也包含列索引。其中,行索引是通过index属性进行获取的,列索引是通过columns属性进行获取的。
虽然DataFrame操作索引能够满足基本数据查看请求,但是仍然不够灵活。为此,Pandas库中提供了操作索引的方法来访问数据,具体包括:
loc:基于标签索引(索引名称),用于按标签选取数据。当执行切片操作时,既包含起始索引,也包含结束索引。
iloc:基于位置索引(整数索引),用于按位置选取数据。当执行切片操作时,只包含起始索引,不包含结束索引。
03 算术运算与数据对齐
算术运算与数据对齐
Pandas执行算术运算时,会先按照索引进行对齐,对齐以后再进行相应的运算,没有对齐的位置会用NaN进行补齐
如果希望不使用NAN填充缺失数据,则可以在调用add方法时提供fill_value参数的值,fill_value将会使用对象中存在的数据进行补充
# 执行加法运算,补充缺失值
obj_one.add(obj_two, fill_value = 0)
04 数据排序
按索引排序
Pandas中按索引排序使用的是sort_index()方法,该方法可以用行索引或者列索引进行排序。
sort_index(axis = 0,level = None,ascending = True,inplace = False,kind =' quicksort ',na_position ='last',sort_remaining = True )
注释:
axis:轴索引,0表示index(按行),1表示columns(按列)。
level:若不为None,则对指定索引级别的值进行排序。
ascending:是否升序排列,默认为True表示升序。
ser_obj = pd.Series(range(10, 15), index=[5, 3, 1, 3, 2])
# 按索引进行升序排列
ser_obj.sort_index()
# 按索引进行降序排列
ser_obj.sort_index(ascending = False)
df_obj = pd.DataFrame(np.arange(9).reshape(3, 3),
index=[4, 3, 5])
# 按行索引升序排列
df_obj.sort_index()
# 按行索引降序排列
df_obj.sort_index(ascending=False)
按值排序
Pandas中用来按值排序的方法为sort_values(),该方法的语法格式如下
sort_values(by,axis=0, ascending=True, inplace=False, kind='quicksort',na_position='last')
by参数表示排序的列,na_position参数只有两个值:first和last,若设为first,则会将NaN值放在开头;若设为False,则会将NaN值放在最后。
ser_obj = pd.Series([4, np.nan, 6, np.nan, -3, 2])
# 按值升序排列
ser_obj.sort_values()
在DataFrame中,sort_values()方法可以根据一个或多个列中的值进行排序,但是需要在排序时,将一个或多个列的索引传递给by参数才行
df_obj = pd.DataFrame([[0.4, -0.1, -0.3, 0.0],
[0.2, 0.6, -0.1, -0.7],
[0.8, 0.6, -0.5, 0.1]])
# 对列索引值为2的数据进行排序
df_obj.sort_values(by=2)
05 统计计算与描述
常用的统计计算
如果希望一次性输出多个统计指标,则我们可以调用describe()方法实现,语法格式如下
describe(percentiles=None, include=None, exclude=None)
注释:
percentiles:输出中包含的百分数,位于[0,1]之间。如果不设置该参数,则默认为[0.25,0.5,0.75],返回25%,50%,75%分位数。
06 层次化索引
认识层次化索引
Series和DataFrame均可以实现层次化索引,最常见的方式是在构造方法的index参数中传入一个嵌套列表
mulitindex_series = pd.Series([15848,13472,12073.8,7813,
7446,6444,15230,8269],
index=[['河北省','河北省','河北省','河北省',
'河南省','河南省','河南省','河南省'],
['石家庄市','唐山市','邯郸市','秦皇岛市',
'郑州市','开封市','洛阳市','新乡市']])
还可以通过MultiIndex类的方法构建一个层次化索引,该类提供了3种创建层次化索引的方法:
MultiIndex.from_tuples():将元组列表转换为MultiIndex。
MultiIndex.from_arrays():将数组列表转换为MultiIndex。
MultiIndex.from_product():从多个集合的笛卡尔乘积中创建一个MultiIndex。
1.from_tuples()方法可以将包含若干个元组的列表转换为MultiIndex对象,其中元组的第一个元素作为外层索引,元组的第二个元素作为内层索引。
list_tuples = [('A','A1'), ('A','A2'), ('B','B1'),('B','B2'), ('B','B3')]
# 根据元组列表创建一个MultiIndex对象
multi_index = MultiIndex.from_tuples(tuples=list_tuples,
names=[ '外层索引', '内层索引'])
2.from_arrays()方法是将数组列表转换为MultiIndex对象,其中嵌套的第一个列表将作为外层索引,嵌套的第二个列表将作为内层索引。
multi_array = MultiIndex.from_arrays(arrays =[['A', 'B', 'A', 'B', 'B'],
['A1', 'A2', 'B1', 'B2', 'B3']],
names=['外层索引','内层索引'])
3.from_product()方法表示从多个集合的笛卡尔乘积中创建一个MultiIndex对象。
numbers = [0, 1, 2]
colors = ['green', 'purple']
multi_product = pd.MultiIndex.from_product(iterables=[numbers, colors],
names=['number', 'color'])
根据书籍统计表,创建一个具有多层索引的Series对象,示例如下:
ser_obj = Series([50, 60, 40, 94, 63, 101, 200, 56, 45],
index=[['小说', '小说', '小说',
'散文随笔', '散文随笔', '散文随笔',
'传记', '传记', '传记'],
['高山上的小邮局', '失踪的总统', '绿毛水怪',
'皮囊', '浮生六记', '自在独行',
'梅西', '老舍自传', '库里传']])
如果商城管理员需要统计小说销售的情况,则可以从表中筛选出外层索引标签为小说的数据。
# 获取所有外层索引为“小说”的数据
ser_obj['小说']
假设当前只知道书名为“自在独行”,但所属的类别和销售数量并不清楚,则需要操作内层索引获取该书籍的类别与销售数量。
# 获取内层索引对应的数据
ser_obj[:,'自在独行']
交换分层顺序是指交换外层索引和内层索引的位置。
在Pandas中,交换分层顺序的操作可以使用swaplevel()方法来完成。
# 交换外层索引与内层索引位置
ser_obj.swaplevel()
要想按照分层索引对数据排序,则可以通过**sort_index()**方法实现。
sort_index(axis = 0,level = None,ascending = True,inplace = False,kind =' quicksort ',na_position ='last',
sort_remaining = True,by = None )
注释:
by:表示按指定的值排序。
ascending:布尔值,表示是否升序排列,默认为True。
在使用sort_index()方法排序时,会优先选择按外层索引进行排序,然后再按照内层索引进行排序。
07 读写数据操作
读写文本文件
to_csv()方法的功能是将数据写入到CSV文件中
to_csv(path_or_buf=None,sep=',',na_rep='',float_format=None,columns=None,header=True, index=True, index_label=None, mode='w‘, ...)
path_or_buf:文件路径。
index:默认为True,若设为False,则将不会显示索引。
sep:分隔符,默认用“,”隔开。
read_csv()函数的作用是将CSV文件的数据读取出来,转换成DataFrame对象展示。
read_csv(filepath_or_buffer,sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, prefix=None, ...)
注释:
sep:指定使用的分隔符,默认用“,”分隔。
header:指定行数用来作为列名。
names:用于结果的列名列表。如果文件不包含标题行,则应该将该参数设置为None
注:Text格式的文件也是比较常见的存储数据的方式,后缀名为".txt",它与上面提到的CSV文件都属于文本文件。
如果希望读取Text文件,既可以用前面提到的read_csv()函数,也可以使用read_table()函数
注:read_csv()与read_table()函数的区别在于使用的分隔符不同,前者使用“,”作为分隔符,而后者使用“\t”作为分隔符。
to_excel()方法的功能是将DataFrame对象写入到Excel工作表中
to_excel(excel_writer,sheet_name='Sheet1',na_rep='',
float_format=None, columns=None, header=True, index=True, ...)
注释:
excel_writer:表示读取的文件路径。
sheet_name:表示工作表的名称,默认为“Sheet1”。
na_rep:表示缺失数据。
index:表示是否写行索引,默认为True。
read_excel()函数的作用是将Excel中的数据读取出来,转换成DataFrame展示。
pandas.read_excel(io,sheet_name=0,header=0,names=None,index_col=None, **kwds)
注释:
io:表示路径对象。
sheet_name:指定要读取的工作表,默认为0。
header:用于解析DataFrame的列标签。
names:要使用的列名称。
在浏览网页时,有些数据会在HTML网页中以表格的形式进行展示。
对于网页中的表格,可以使用read_html()函数进行读取,并返回一个包含多个DataFrame对象的列表。
pandas.read_html(io, match='.+', flavor=None,header=None, index_col=None,skiprows=None, attrs=None)
注释:
io:表示路径对象。
header:表示指定列标题所在的行。
index_col:表示指定行标题对应的列。
attrs:默认为None,用于表示表格的属性值。
读写数据库
在连接mysql数据库时,这里使用的是mysqlconnector驱动,如果当前的Python环境中没有改模块,则需要使用pip install mysqlconnector命令安装该模块。
read_sql()函数既可以读取整张数据表,又可以执行SQL语句
pandas.read_sql(sql,con,index_col=None,coerce_float=True,params=None,parse_dates=None, columns=None, chunksize=None)
注释:sql:表示被执行的SQL语句。
con:接收数据库连接,表示数据库的连接信息。
columns:从SQL表中选择列名列表。
注:通过create_engine()函数创建连接时,需要指定格式如下:‘数据库类型+数据库驱动名称://用户名:密码@机器地址:端口号/数据库名’。
to_sql()方法的功能是将Series或DataFrame对象以数据表的形式写入到数据库中
to_sql(name,con,schema = None,if_exists ='fail',index = True,index_label = None,chunksize = None,dtype = None )
注释:name:表示数据库表的名称。
con: 表示数据库的连接信息。
if_exists:可以取值为fail、replace或append,默认为’fail’。
本章小结
数据预处理
01 数据清洗
空值和缺失值的处理
空值一般表示数据未知、不适用或将在以后添加数据。缺失值是指数据集中某个或某些属性的值是不完整的
注:一般空值使用None表示,缺失值使用NaN表示
Pandas中提供了一些用于检查或处理空值和缺失值的函数或方法。
使用isnull()和notnull()函数可以判断数据集中是否存在空值和缺失值。
对于缺失数据可以使用dropna()和fillna()方法对缺失值进行删除和填充。
pandas.isnull(obj)
注释:上述函数中只有一个参数obj,表示检查空值的对象。
isnull()函数会返回一个布尔类型的值,如果返回的结果为True,则说明有空值或缺失值,否则为False。(NaN或None映射到True值,其它内容映射到False)
notnull() 与isnull()函数的功能是一样的,都可以判断数据中是否存在空值或缺失值,不同之处在于,前者发现数据中有空值或缺失值时返回False,后者返回的是True。
series_obj = Series([1, None, NaN])
# 检查是否不为空值或缺失值
pd.notnull(series_obj)
dropna()方法的作用是删除含有空值或缺失值的行或列
dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
注释: axis:确定过滤行或列。
how:确定过滤的标准。
thresh:表示有效数据量的最小要求。若传入了2,则是要求该行或该列至少有两个非NaN值时将其保留。
删除空值或缺失值前后的效果如下图所示:
填充缺失值和空值的方式有很多种,比如人工填写、热卡填充等,Pandas中的fillna()方法可以实现填充空值或缺失值
fillna(value=None, method=None, axis=None, inplace=False,limit=None, downcast=None, **kwargs)
注释:value:用于填充的数值。
method:表示填充方式,默认值为None。
limit: 可以连续填充的最大数量,默认None。
注:method参数不能与value参数同时使用
例:有一张表格里存在缺失值,如果使用常量66.0来替换缺失值,那么填充前后的效果如下图所示
通过fillna()方法填充常量的示例如下:
# 使用66.0替换缺失值
df_obj.fillna('66.0')
例:如果希望A列缺失的数据使用数字“4.0”进行填充,B列缺失的数据使用数字“5.0”来填充,那么填充前后的效果如下图所示。
通过fillna()方法对指定列进行填充的示例如下:
# 指定列填充数据
df_obj.fillna({'A': 4.0, 'B': 5.0})
例:如果希望A~D列中按从前往后的顺序填充缺失的数据,那么填充前后的效果如下图所示。
通过fillna()方法采用前向填充的方式替换空值或缺失值,示例如下:
# 使用前向填充的方式替换空值或缺失值
df.fillna(method='ffill')
重复值的处理
当数据中出现了重复值,在大多数情况下需要进行删除。
Pandas提供了两个函数专门用来处理数据中的重复值,分别为duplicated()和drop_duplicates()方法
duplicated()方法用于标记是否有重复值。
drop_duplicates()方法用于删除重复值。
它们的判断标准是一样的,即只要两条数据中所有条目的值完全相等,就判断为重复值。
duplicated()方法的语法格式如下:
duplicated(subset=None, keep='first')
注释:subset:用于识别重复的列标签或列标签序列,默认识别所有的列标签。
keep:删除重复项并保留第一次出现的项,取值可以为first、last或False。
注:duplicated()方法用于标记Pandas对象的数据是否重复,重复则标记为True,不重复则标记为False,所以该方法返回一个由布尔值组成的Series对象,它的行索引保持不变,数据则变为标记的布尔值。
对于duplicated()方法,这里有如下两点要进行强调:
(1)只有数据表中两个条目间所有列的内容都相等时,duplicated()方法才会判断为重复值。
(2)duplicated()方法支持从前向后(first)和从后向前(last)两种重复值查找模式,默认是从前向后查找判断重复值的。换句话说,就是将后出现的相同条目判断为重复值。
drop_duplicates()方法的语法格式如下:
drop_duplicates(subset=None, keep='first', inplace=False)
注释:上述方法中,inplace参数接收一个布尔类型的值,表示是否替换原来的数据,默认为False
异常值的处理
异常值是指样本中的个别值,其数值明显偏离它所属样本的其余观测值,这些数值是不合理的或错误的
要想确认一组数据中是否有异常值,则常用的检测方法有3σ原则(拉依达准则)和箱形图。
3σ原则是基于正态分布的数据检测,而箱形图没有什么严格的要求,可以检测任意一组数据
注:3σ原则,又称为拉依达原则,它是指假设一组检测数据只含有随机误差,对其进行计算处理得到标准偏差,按一定概率确定一个区间,凡是超过这个区间的误差都是粗大误差,在此误差的范围内的数据应予以剔除。
在正态分布概率公式中,σ表示标准差,μ表示平均数,f(x)表示正态分数函数,具体如下:
根据正态分布函数图可知,3σ原则在各个区间所占的概率如下所示:
(1)数值分布在(μ-σ,μ+σ)中的概率为0.682。
(2)数值分布在(μ-2σ,μ+2σ)中的概率为0.954。
(3)数值分布在(μ-3σ,μ+3σ)中的概率为0.997。
注:数值几乎全部集中在(μ-3σ,μ+3σ)]区间内,超出这个范围的可能性仅占不到0.3%。所以,凡是误差超过这个区间的就属于异常值,应予以剔除。
箱形图是一种用作显示一组数据分散情况的统计图。在箱形图中,异常值通常被定义为小于QL – 1.5QR或大于QU + 1.5IQR的值
(1)QL称为下四分位数,表示全部观察中四分之一的数据取值比它小;
(2)QU称为上四分位数,表示全部观察值中有四分之一的数据取值比它大;
(3)IQR称为四分位数间距,是上四分位数QU与下四分位数QL之差,其间包含了全部观察值的一半。
离散点表示的是异常值,上界表示除异常值以外数据中最大值;下界表示除异常值以外数据中最小值。
为了能够从箱形图中查看异常值,Pandas中提供了一个boxplot()方法,专门用来绘制箱形图。
从输出的箱形图中可以看出,D列的数据中有一个离散点,说明箱形图成功检测出了异常值。
检测出异常值后,通常会采用如下四种方式处理这些异常值:
直接将含有异常值的记录删除。
用具体的值来进行替换,可用前后两个观测值的平均值修正该异常值。
不处理,直接在具有异常值的数据集上进行统计分析。
视为缺失值,利用缺失值的处理方法修正该异常值。
如果希望对异常值进行修改,则可以使用replace()方法进行替换,该方法不仅可以对单个数据进行替换,也可以多个数据执行批量替换操作
replace(to_replace = None,value = None,inplace = False,limit = None,regex = False,method ='pad' )
注释:to_replace:表示查找被替换值的方式。
value:用来替换任何匹配to_replace的值,默认值None。
更改数据类型
创建Pandas数据对象时,如果没有明确地指出数据的类型,则可以根据传入的数据推断出来,并且通过dtypes属性进行查看。
df = pd.DataFrame({'A': ['5', '6', '7'],
'B': ['3', '2', '1']},dtype='int')
df.dtypes
通过astype()方法可以强制转换数据的类型。
astype(dtype,copy = True,errors ='raise',** kwargs )
注释:dtype:表示数据的类型。
errors:错误采取的处理方式,可以取值为raise或ignore。其中,raise表示允许引发异常,ignore表示抑制异常,默认为raise。
注:astype()方法存在着一些局限性,只要待转换的数据中存在非数字以外的字符,在使用astype()方法进行类型转换时就会出现错误,而to_numeric()函数的出现正好解决了这个问题。
to_numeric
pandas.to_numeric(arg, errors='raise', downcast=None)
注释:arg:表示要转换的数据,可以是list、tuple、Series。
errors:表示错误采取的处理方式。
02 数据合并
轴向堆叠数据
concat()函数可以沿着一条轴将多个对象进行堆叠,其使用方式类似数据库中的数据表合并。
concat(objs,axis=0,join=‘outer’,join_axes=None,ignore_index=False,keys=None,levels=None,names=None, ...)
axis:表示连接的轴向,可以为0或1,默认为0。
join:表示连接的方式,inner表示内连接,outer表示外连接,默认使用外连接。
ignore_index:如果设置为True,清除现有索引并重置索引值。
names:结果分层索引中的层级的名称。
注:根据轴方向的不同,可以将堆叠分成横向堆叠与纵向堆叠,默认采用的是纵向堆叠方式。
在堆叠数据时,默认采用的是外连接(join参数设为outer)的方式进行合并,当然也可以通过join=inner设置为内连接的方式。
当使用concat()函数合并时,若是将axis参数的值设为1,且join参数的值设为outer,代表着使用横向堆叠与外连接的方式进行合并。
当使用concat()函数合并时,若是将axis参数的值设为0,且join参数的值设为inner,则代表着使用纵向堆叠与内连接的方式进行合并。
主键合并数据
主键合并类似于关系型数据库的连接方式,它是指根据一个或多个键将不同的DatFrame对象连接起来,大多数是将两个DatFrame对象中重叠的列作为合并的键。
Pandas中提供了用于主键合并的merge()函数。
pandas.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, validate=None)
注释: left:参与合并的左侧DataFrame对象。
right:参与合并的右侧DataFrame对象。
how:表示连接方式,默认为inner。
left:使用左侧的DataFrame的键,类似SQL的左外连接。
right:使用右侧的DataFrame的键,类似SQL的右外连接。
outer:使用两个DataFrame所有的键,类似SQL的全连接。
inner:使用两个DataFrame键的交集,类似SQL的内连接
在使用merge()函数进行合并时,默认会使用重叠的列索引做为合并键,并采用内连接方式合并数据,即取行索引重叠的部分。
除此之外,merge()函数还支持对含有多个重叠列的DataFrame对象进行合并。
使用外连接的方式将left与right进行合并时,列中相同的数据会重叠,没有数据的位置使用NaN进行填充。
左连接是以左表为基准进行连接,所以left表中的数据会全部显示,right表中只会显示与重叠数据行索引值相同的数据,合并后表中缺失的数据会使用NaN进行填充。
右连接与左连接的规则正好相反,右连接是以右表为基准,右表中的数据全部显示,而左表中显示与重叠数据行索引值相同的数据,合并后缺失的数据使用NaN填充合并。
假设两张表中的行索引与列索引均没有重叠的部分,但依旧可以使用merge函数来合并,只需要将参数left_index与right_index的值设置为True即可。
根据行索引合并数据
join()方法能够通过索引或指定列来连接多个DataFrame对象。
join(other,on = None,how ='left',lsuffix ='',rsuffix ='',sort = False )
注释:on:名称,用于连接列名。
how:可以从{’‘left’’ ,’‘right’’, ‘‘outer’’, ‘‘inner’’}中任选一个,默认使用左连接的方式。
sort:根据连接键对合并的数据进行排序,默认为False。
合并重叠数据
当DataFrame对象中出现了缺失数据,而我们希望使用其他DataFrame对象中的数据填充缺失数据,则可以通过combine_first()方法为缺失数据填充。
combine_first(other)
注:上述方法中只有一个参数other,该参数用于接收填充缺失值的DataFrame对象。
假设现在有left表与right表,其中left表中存在3个缺失的数据,而right表中的数据是完整的,并且right表与left表有相同的索引名,此时我们可以使用right表中的数据来填充left表的缺失数据,得到一个新的result表,
03 数据重塑
重塑层次化索引
Pandas中重塑层次化索引的操作主要是stack()方法和unstack()方法,前者是将数据的列“旋转”为行,后者是将数据的行“旋转”为列。
stack()方法可以将数据的列索引转换为行索引。
DataFrame.stack(level=-1, dropna=True)
注释:level:表示操作内层索引。若设为0,表示操作外层索引,默认为-1。dropna:表示是否将旋转后的缺失值删除,若设为True,则表示自动过滤缺失值,设置为False则相反。
现在有一个DataFrame类对象df,如果希望将它重塑为一个具有两层索引结构的对象result,也就是说将列索引转换成内层行索引,则重塑前后的效果如下图所示。
unstack()方法可以将数据的行索引转换为列索引。
DataFrame.unstack(level=-1, fill_value=None)
注释:level:默认为-1,表示操作内层索引,0表示操作外层索引。fill_value:若产生了缺失值,则可以设置这个参数用来替换NaN。
轴向旋转
某件商品的价格在非活动期间为50元,而在活动期间商品的价格为30元,这就造成同一件商品在不同时间对应不同的价格。
同一款商品的在活动前后的价格无法很直观地看出来。
我们可以将商品的名称作为列索引,出售日期作为行索引,价格作为表格中的数据,此时每一行展示了同一日期不同手机品牌的价格。
通过表格可以直观地看出活动前后的价格浮动
在Pandas中pivot()方法提供了这样的功能,它会根据给定的行或列索引重新组织一个DataFrame对象。
pivot(index=None, columns=None, values=None)
注释:index:用于创建新DataFrame对象的行索引。columns:用于创建新DataFrame对象的列索引。values:用于填充新DataFrame对象中的值。
04 数据转换
重命名轴索引
Pandas中提供了一个rename()方法来重命名个别列索引或行索引的标签或名称。
rename(mapper = None,index = Nonecolumns = None,axis = None,copy = True,inplace = False,level = None)
注释:index,columns:表示对行索引名或列索引名的转换。inplace:默认为False,表示是否返回新的Pandas对象。
例如,将df对象的每个列索引名称重命名为a、b、c。
离散化连续数据
有时候我们会碰到这样的需求,例如,将有关年龄的数据进行离散化(分桶)或拆分为“面元”,直白来说,就是将年龄分成几个区间。
Pandas 的 cut ()函数能够实现离散化操作
pandas.cut(x,bins,right = True,labels = None,retbins = False,precision = 3,include_lowest = False,duplicates ='raise' )
注释:x:表示要分箱的数组,必须是一维的。
bins:接收int和序列类型的数据。
right:是否包含右端点,决定区间的开闭,默认为True。
注:cut()函数会返回一个Categorical对象,我们可以将其看作一组表示面元名称的字符串,它包含了分组的数量以及不同分类的名称。
Categories对象中的区间范围跟数学符号中的“区间”一样,都是用圆括号表示开区间,用方括号则表示闭区间
如果希望设置左闭右开区间,则可以在调用cut()函数时传入right=False进行修改。
pd.cut(ages, bins=bins, right=False)
哑变量处理类别型数据
哑变量又称虚拟变量、名义变量,从名称上看就知道,它是人为虚设的变量,用来反映某个变量的不同类别。使用哑变量处理类别转换,事实上就是将分类变量转换为哑变量矩阵或指标矩阵,矩阵的值通常用“0”或“1”表示
假设变量“职业”的取值分别为司机、学生、导游、工人、教师共5种选项,如果使用哑变量表示,则可以用下图表示。
在Pandas中,可以使用get_dummies()函数对类别特征进行哑变量处理,
pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False,columns=None, sparse=False, drop_first=False, dtype=None)
注释:data:表示哑变量处理的数据。
prefix:表示列名的前缀,默认为None。
prefix_sep:用于附加前缀作为分隔符使用,默认为“_”。