目录
- Pandas部分应掌握的重要知识点
- 一、DataFrame数据框的创建
- 1、直接基于二维数据创建(同时使用index和columns参数)
- 2、基于excel文件中的数据来创建
- 二、查看数据框中的数据和联机帮助信息
- 1、查看特殊行的数据
- 2、查看联机帮助的两种常见方法(help和?)
- 3、查看总体统计情况
- 4、根据指定行号或列号查看数据
- 5、根据行标签或列标签查看数据
- 6、根据给定条件查询数据
- 三、对数据框进行增删改操作
- 1、在数据框的尾部增加一列
- 2、在尾部增加一行
- 3、修改一列数据
- 4、修改一行数据
- 5、删除一列或多列数据
- 6、删除一行数据
- 四、数据框的合并
- 1、merge合并
- 2、concat合并
- 3、join合并
- 五、分组及相关计算
- 1、分组及统计
- 2、找到满足条件的分组(过滤掉不满足条件的分组)
- 六、处理缺失值
- 1、Pandas中缺失值的表示
- 2、 与缺失值判断和处理相关的方法
- 3、 填充缺失值
Pandas部分应掌握的重要知识点
import numpy as np
import pandas as pd
一、DataFrame数据框的创建
1、直接基于二维数据创建(同时使用index和columns参数)
scores=np.array([[97,93,86],[95,97,88]])
pd.DataFrame(scores,index=['s01','s02'],columns=['数学','英语','语文'])
2、基于excel文件中的数据来创建
数据集team.xlsx下载地址:下载team.xlsx
team=pd.read_excel('team.xlsx')
team.head()
二、查看数据框中的数据和联机帮助信息
1、查看特殊行的数据
(1)查看前n行:head(n)
,不指定n时默认前5行。
team.head(3)
(2)查看后n行:tail(n)
,不指定n时默认后5行。
team.tail()
(3)随机抽样查看n行:sample(n)
,不指定n时默认抽样1行数据。
team.sample(2)
2、查看联机帮助的两种常见方法(help和?)
team.sample?
#也可以使用help(team.sample)查看帮助:
#help(team.sample)
3、查看总体统计情况
team.describe() #技巧:输入des后按键盘的tab键可以实现命令补全
4、根据指定行号或列号查看数据
(1)通用写法:因为行号/列号是整数,所以需要使用.iloc
位置索引器。索引器中括号内行列下标的位置上都允许使用切片和花式索引,下例中行使用切片,列使用花式索引。
注意:下面的3:5
表示下标为3和4的两行,[0,2]
表示下标为0和2的两列。
team.iloc[3:5,[0,2]]
(2)当只按行下标查看多个连续的行数据时,可以采用以下简化写法(不使用索引器):
team[10:13]
注意:
① 该简化方法等价于team.iloc[10:13,:]
,但更推荐.iloc
的写法,因为后者更通用;
② 该简化写法下,即使查看一行数据,也要使用切片的形式,例如:team[10:11]
可以查看下标为10的行。
5、根据行标签或列标签查看数据
(1)通用方法:因为行标签或列标签通常是字符串,所以需要使用.loc标签索引器。索引器中括号内行列下标的位置上都允许使用切片和花式索引,下例中行使用切片,列使用花式索引。
注意:下面的3:4
表示行标签为3和4的两行,["name","Q1"]
表示列标签为"name"和"Q1"的两列。
team.loc[3:4,["name","Q1"]]
特别提醒,虽然上述两种通用写法的输出相同,但原理不同:
① iloc
索引器的切片不包含终值,所以team.iloc[3:5,[0,2]]
中不包含下标为5的行;
② loc
索引器的切片却包含终值,所以team.loc[3:4,[0,2]]
中却包含行标签为4的行;
③ 同样是整数,在iloc
索引器中将被解读为行/列下标,而在loc
索引器中将被解读为行/列标签。
(2)当只涉及到按列标签查看数据时,可以使用下列简化方法(不使用索引器):
print(team['team'].unique()) #按列标签选择一列
team[['name','Q1']].head(3) #按列标签选择多列,使用花式索引的形式
补充说明:使用.iloc
或loc
索引器的通用写法适用性更广泛,因此掌握通用写法是基本要求,在此基础上最好能掌握基于列标签的简化写法,因为这种写法也比较常见
6、根据给定条件查询数据
实现要领有两个:
① 因为多数条件都会涉及列标签,因此都要使用loc
索引器(而非iloc
索引器);
② 因为通常是寻找满足条件的行,所以索引器内部需要在行的维度上表达查询条件。
即查询条件写在行索引处(英文逗号左侧),而需要的列写在列索引处(逗号右侧)。
(1)以下是查询第一季度销售额大于90的人员姓名:
team.loc[team['Q1']>90,'name']
#与上面等价但不推荐的写法:
#team[team['Q1']>90]['name']
(2)查询姓名以字母’M’开头的人前两个季度的销售情况:
此处用到了Series对象的str属性的相关方法:关于Series对象的str属性的介绍
team.loc[team['name'].str.startswith('M'),['name','Q1','Q2']]
#通过set_index函数可以把name列作为新的行标签
if team.index.name!='name':team.set_index("name",inplace=True)
#再次查询姓名以字母'M'开头的人四个季度的销售情况:
team.loc[team.index.str.startswith('M'),'Q1':'Q4']
三、对数据框进行增删改操作
1、在数据框的尾部增加一列
df = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'],'group': ['Accounting', 'Engineering', 'Engineering', 'HR']})
print("增加性别列之前:\n",df)
sex_value=pd.Series(['M','M','F','F'])
salary_value=[6000,5000,4000,3000]
#在尾部增加一列:采用赋值法
df['sex']=sex_value
df['salary']=salary_value
print("增加性别和工资列之后:")
df
2、在尾部增加一行
注意:此处只能使用loc
索引器(使用iloc
会出现索引越界的提示)。
索引器中的len(df)
是想把当前数据框的长度作为新增加行的行标签。
df.loc[len(df),:]=['Mike','Guarding','M',2000]
print("在尾部增加一行之后:")
df
3、修改一列数据
修改一列数据仍采用对列进行赋值操作的形式。下面把性别列的值都设置为"Unknown"
。
new_sex=len(df)*["Unknown"]
print(new_sex)
df['sex']=new_sex
print("修改性别列之后:")
df
4、修改一行数据
可以使用loc
索引器结合赋值操作来修改:
下面把标签为2的那行数据修改为["Rose","Sales","Female"]
。
df.loc[2,:]=["Rose","Sales","Female",3500]
print("修改标签为2的行之后:")
df
5、删除一列或多列数据
使用drop
函数,并且指定axis=1
才能删除列。
如果要删除多列,则要结合标签的花式索引形式:
df.drop(['sex','salary'],axis=1,inplace=True) #inplace=True表示原地修改,即修改的结果直接作用于当前对象
print("删除性别和工资列之后:")
df
6、删除一行数据
使用drop
函数,默认是删除行(axis=0
是默认值)。
以下是删除标签为4的行:
df.drop(4,inplace=True)
print("删除标签为4的行之后:")
df
说明:可以通过?或help来查看以上操作函数的参数,例如df.drop?
可以查看drop函数的相关帮助信息。
四、数据框的合并
问题:有两个数据框,如下图所示,现在期望将它们合并成如下图所示的效果,该如何做?
数据框df2:
数据框df3:
df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'],'hire_date': [2004, 2008, 2012, 2014]})
df2
df3 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue','Tom'],'group': ['Accounting', 'Engineering', 'Engineering', 'HR',np.NaN]})
df3 #注意Tom目前没有所属部门
1、merge合并
merge主要基于列值匹配而进行列合并,类似于SQL中的连接操作。
df4_1=pd.merge(df3,df2) #效果等价于how='right'
df4_1
df4_2=pd.merge(df3,df2,how='outer') #效果等价于how='left'
df4_2
2、concat合并
df5=pd.concat([df3,df2])
df5
3、join合并
df6=df3.join(df2,lsuffix='_l', rsuffix='_r')
df6
小结:
concat
默认的合并方式是行拼接,取并集(axis=0,join='outer'
)merge
默认的合并方式是基于列值进行列拼接,取交集(how='inner'
)join
默认的合并方式是基于行索引进行列合并,并且默认为左连接
五、分组及相关计算
1、分组及统计
针对team
数据框,要求按’team’列统计各团队前两个季度的平均销售额:
方法1:先分组再选择列最后计算,推荐此种写法。
#注意本例中,选择两列时使用了花式索引()
team.groupby('team')[['Q1','Q2']].mean()#如果如果只有一列,则无需使用花式索引,如下所示:
#team.groupby('team')['Q1'].mean()
方法2:先分组再计算最后选择列
#注意本例中,选择两列时使用了花式索引(如果只有一列,则无需使用花式索引)
team.groupby('team').mean()[['Q1','Q2']]#如果如果只有一列,则无需使用花式索引,如下所示:
#team.groupby('team').mean()['Q1']
2、找到满足条件的分组(过滤掉不满足条件的分组)
现在要求找到前两个季度平均销售额都大于45的团队,显然这是一个对分组进行过滤的任务。
该任务可以分两步进行:
#(1)用filter函数得到满足所需条件的分组中的记录,它的结果是整个数据集的子集
flt_df=team.groupby('team').filter(lambda x: (x['Q1'].mean()>45) & (x['Q2'].mean()>45))#(2)再对该子集重新进行一次分组汇总统计
flt_df.groupby('team')[['Q1','Q2']].mean()
补充说明:
① filter
函数用于对分组进行过滤(类似于SQL中的having子句)
② filter
函数返回满足过滤条件的分组中的记录,而不是满足条件的分组
③ 其参数必须是函数,本例中lambda
函数的形参x
代表每个分组
④ 当组对象存在多列时,filter
的过滤条件要求显式的指定某一列
六、处理缺失值
1、Pandas中缺失值的表示
Pandas表示缺失值的一种方法是使用NaN
(Not a Number),它是一个特殊的浮点数;另一种是使用Python中的None
;Pandas会自动把None
转变成NaN
。
data=pd.Series([1, np.nan, 'hello', None])
data
2、 与缺失值判断和处理相关的方法
isnull()
: 判断每个元素是否是缺失值,会返回一个与原对象尺寸相同的布尔性Pandas对象notnull()
: 与isnull()相反dropna()
: 返回一个删除缺失值后的数据对象fillna()
: 返回一个填充了缺失值之后的数据对象
(1)判断是否含有缺失值:
data.isnull()
(2)统计一维的data中缺失值的个数:
data.isnull().sum()
2
(3)统计二维的df中缺失值的个数:
df = pd.DataFrame([[1, np.nan, 2],[2, 3, 5],[np.nan, 4, 6]])
df.isnull().sum().sum()
2
(4)dropna
默认删除任何包含缺失值的整行数据:
df.dropna()
(5)使用axis=1
或axis='columns'
删除任何包含缺失值的整列数据:
df.dropna(axis=1)
(6)更精确的缩小删除范围,需要使用how
或thresh
(阈值)参数。只有全为空值的列才会被删除。
df.dropna(axis='columns', how='all')
3、 填充缺失值
(1)用单个值填充,下面的例子使用0来填充缺失值:
df.fillna(0)
(2)从前向后填充(forward-fill):
df.fillna(method='ffill')
(3)从后向前填充(back-fill):
df.fillna(method='bfill')
(4)插值法填充
下面的示例:线性插值、沿着水平方向从前向后填充。填充的方向默认是axis=0
,即垂直方向填充;如果希望水平方向填充,需要设置axis=1
。
df.interpolate(method='linear', limit_direction='forward', axis=1)
(5)上面的方法都不是原地修改原对象,如果需要原地修改,则需要设置inplace=True
。
print(df)
df.interpolate(method='linear', limit_direction='forward', axis=1,inplace=True)
df