数据预览
-
首先,调用
read_excel()
方法读取数据import pandas as pd df = pd.read_excel("data.xlsx") df 姓名 班级 语文 数学 0 张三 一班 99 90 1 李四 一班 78 NaN 2 王五 一班 70 88 3 小明 二班 88 99 4 小红 二班 98 77
-
导入数据后,首先要熟悉数据。
-
shape属性:可以帮助我们查看数据包含几行几列
df.shape (5,4)
从结果可以看出,这份数据一共有5行4列
-
**head()或tail()**方法:head()方法可以帮助我们查看数据的前几行,tail()方法可以帮助我们查看数据的后几行
df.head() 姓名 班级 语文 数学 0 张三 一班 99 90 1 李四 一班 78 NaN 2 王五 一班 70 88 3 小明 二班 88 99 4 小红 二班 98 77 df.tail(2) 姓名 班级 语文 数学 3 小明 二班 88 99 4 小红 二班 98 77
head()方法默认展示的是前5行数据,tail()方法默认展示的是后5行数据。当他们传入指定数字时,就可以帮我们获取指定的行数。
-
dtypes
属性:可以帮助我们查看每列数据的数据类型df.dtypes 姓名 object 班级 object 语文 int64 数学 int64 dtype object
object
类型是字符串,int64
是整型,float64
是浮点型 -
**describe()**方法:可以帮助我们查看数值型变量的描述性统计量
df.describe() 语文 数学 count mean std min 25% 50% 75% max
count
表示计数,mean
表示平均值,std
表示标准差,min
和max
分别表示最小值和最大值,25%
、50%
、75%
表示四分位数 -
**info()**方法:可以帮助我们查看数据的列名、数据类型、非空值、以及内存占用情况
df.info() <class "pandas.core.frame.DataFrame"> RangeIndex: 6 entries, 0 to 5 Data columns (total 5 columns): # Column Non-Null Count Dtype -- ----- ------- ----- ----- 0 姓名 6 non-null object 1 班级 6 non-null object 2 语文 6 non-null int64 3 数学 5 non-null int64 dtypes: int64(2),object(2) memory usage: 368.0+ bytes
可以清楚的看到每一个列字段的列名、非空值和数据类型。另外“数学”这一列只有5个非空值,表明该列存在缺失值。同时
memory usage
为我们展示了这份数据占用内存的大小
-
数据预处理
通过数据预览,可以做到对数据心中有数。然而,在正式进行数据处理之前,我们必须进行数据预处理,它直接关系到分析结果的准确性。
有些数据会存在缺失值(NaN
)、重复值
-
检测缺失值
-
其实检测缺失值最简单的方法就是调用**
info()
**方法,通过观察每一列的非空值,即可判断出哪些列存在缺失值 -
另外还有一种检测是否存在缺失值的方法,即**
isnull()
方法搭配any()
**方法,具体介绍如下-
isnull()
:对于缺失值,返回True;对于非缺失值,返回False -
any()
:一个序列中有一个True,则返回True,否则返回Falsedf.isnull() ###打印出每个数据的True或False值 姓名 班级 语文 数学 英语 0 False False False False False 1 False False False True False 2 False False False False False 3 False False False False False 4 False False False False False 5 False False False False False df.isnull().any(axis=1) ###axis=1,可以帮助我们打印出每一行是否存在缺失值 0 False 1 True 2 False 3 False 4 False 5 False df.isnull().any() ###不指定打印的是每一列 是否存在缺失值 姓名 False 班级 False 语文 False 数学 True 英语 False
-
-
-
检测重复值
-
调用**duplicated()**方法,可以用于检测重复值
df.duplicated() 0 False 1 False 2 True 3 False 4 False 5 False df.duplicated().any() True
调用duplicated()方法,可以返回某一行是否是重复值。由于第4行和第3行的数据属于重复行,因此返回True。接着使用any()方法,即可判断出数据中存在重复值
-
-
缺失值处理
-
通常使用
NaN
表示缺失值。如果存在缺失值,我们可以调用**fillna()
方法来填充数据。也可以用dropna()
**方法删除缺失值df = df.fillna(0) ###将NaN修改为0 df = df.dropna() ###将有缺失值的一行删除
-
-
重复值处理
-
**drop_duplicates()**方法,它可以对所有值进行重复值判断,并默认保留第一个(行)值
df 姓名 年龄 0 张三 19 1 张三 19 2 李四 20 df = df.drop_duplicates() 姓名 年龄 0 张三 19 2 李四 20
可以帮我们删除重复行,只保留第一行的数据
-
-
数据替换
-
调用**replace()**方法,可以实现数据替换,例如
replace(A,B)
,表示直接将A替换成Bdf['数学'] = df['数学'].replace(0,90)
-
数据选取
-
按行/列筛选,
loc
和iloc
两种方法,用于行/列筛选-
loc
:利用标签索引的方式获取行或列 -
iloc
:利用位置索引的方式获取行或列选取一列 df['f'] df.loc[:,'f'] df.iloc[:,[1]] 选取多列 df[['e','f']] df.loc[:,['e','f']] df.iloc[:,[0,1]] 选取一行 df.loc['b',:] df.iloc[1,:] 选取多行 df.loc[['a','b'],:] df.iloc[[0,1],:] 同时选取行列 df.loc['b','f'] df.iloc[1,1] 同时选取多行多列 df.loc[['a','b'],['f','g']] df.iloc[[0,1],[1,2]]
df = df.set_index("姓名") df 班级 语文 数学 英语 姓名 赵一 一班 98 96.0 97 王二 一班 88 90.0 75 张三 一班 86 87.0 93 李四 二班 93 92.0 81 朱五 二班 95 99.0 60 df.loc[['赵一','李四']] 班级 语文 数学 英语 姓名 赵一 一班 98 96.0 97 李四 二班 93 92.0 81 df.iloc[[0,3]] 班级 语文 数学 英语 姓名 赵一 一班 98 96.0 97 李四 二班 93 92.0 81
调用set_index()方法,我们将数据框中的“姓名“列设置为新的索引。我们既可以用
loc
传入标签索引的方式,获取这两位同学的数据信息,也可以用iloc
传入位置索引的方式获取信息
-
-
按条件筛选,有时候我们想要筛选出符合某些条件的数据,提供了**
query()
、isin()
、between()
**-
筛选数学成绩在95分以上的同学
df[df['数学']>95]
-
筛选语文和数学成绩都在90分以上的同学
df.query("语文>90 & 数学>90")
-
筛选语文成绩是88或95的同学
df[df['语文'].isin(['88','95'])]
-
筛选数学成绩在85到95之间的同学
df[df['数学'].between(85,95)] ###不包含边界值85和95
-
数据运算
方法 | 作用 | 方法 | 作用 |
---|---|---|---|
sum() | 求和 | abs() | 求绝对值 |
count() | 计数 | mod() | 求余数 |
mean() | 求均值 | value_counts() | 求每个值出现的个数 |
max() | 求最大值 | prod() | 求连乘积 |
min() | 求最小值 | argmax() | 求最大值的索引值 |
mode() | 求众数 | idxmax() | 求最大值的索引值 |
var() | 求方差 | argmin() | 求最小值的索引值 |
std() | 求标准差 | idxmin() | 求最小值的索引值 |
median() | 求中位数 | unique() | 去重(唯一值) |
-
计算每个人的总成绩
df['总分'] = df['语文'] + df['数学'] + df['英语'] df 姓名 班级 语文 数学 英语 总分 0 赵一 一班 98 96.0 97 291.0 1 王二 一班 88 90.0 75 253.0 2 张三 一班 86 87.0 93 266.0 3 李四 二班 93 92.0 81 266.0 4 朱五 二班 95 99.0 60 254.0
-
如果想计算出每个班级的总人数,应该怎么做
df['班级'].value_counts() 一班 3 二班 2 Name: 班级, dtype:int64
-
计算出每个人的平均分,并保留两位小数
df['平均分']=df['总分'].apply(lambda x: round(x/3,2)) df 姓名 班级 语文 数学 英语 总分 平均分 0 赵一 一班 98 96.0 97 291.0 97.00 1 王二 一班 88 90.0 75 253.0 84.33 2 张三 一班 86 87.0 93 266.0 88.67 3 李四 二班 93 92.0 81 266.0 88.67 4 朱五 二班 95 99.0 60 254.0 84.67
apply()将”总分“这一列的每个元素,都除以3且结果保留两位小数。
相当于
a=[1,2,3,4,5] c=list(map(lambda x:x-1,a)) print(c) [0, 1, 2, 3, 4]
-
数据排序与排名
-
数据排序:sort_value()方法可以实现
DataFrame.sort_value(by,ascending,inplace) by:列名(字符/字符列表) ascending:是否升序排序,默认为升序:True inplace:是否修改原DataFrame
-
按照总分降序排序
df.sort_values(by = ["总分"],ascending=False,inplace=True) df 姓名 班级 语文 数学 英语 总分 平均分 0 赵一 一班 98 96.0 97 291.0 97.00 2 张三 一班 86 87.0 93 266.0 88.67 3 李四 二班 93 92.0 81 266.0 88.67 4 朱五 二班 95 99.0 60 254.0 84.67 1 王二 一班 88 90.0 75 253.0 84.33 ###如果总分相同,再按英语来排序 df.sort_values(by = ["总分","英语"],ascending=[False,True],inplace=True) df 姓名 班级 语文 数学 英语 总分 平均分 0 赵一 一班 98 96.0 97 291.0 97.00 3 李四 二班 93 92.0 81 266.0 88.67 2 张三 一班 86 87.0 93 266.0 88.67 4 朱五 二班 95 99.0 60 254.0 84.67 1 王二 一班 88 90.0 75 253.0 84.33
-
数据排名
-
当我们对数据完成排序后,就可以进行数据排名了。调用rank()方法可以实现。
DataFrame.rank(method,ascending) method:排序方式 ascending:是否升序排序,默认为True
-
method有5个常用选项
-
first
姓名 总分 排名 赵一 291 1 张三 266 2 李四 266 3 朱五 254 4 王二 253 5 -
average
姓名 总分 排名 赵一 291 1 张三 266 2.5 李四 266 2.5 朱五 254 4 王二 253 5 -
min
姓名 总分 排名 赵一 291 1 张三 266 2 李四 266 2 朱五 254 4 王二 253 5 -
max
姓名 总分 排名 赵一 291 1 张三 266 3 李四 266 3 朱五 254 4 王二 253 5 -
dense
姓名 总分 排名 赵一 291 1 张三 266 2 李四 266 2 朱五 254 3 王二 253 4
-
-
-
按照总分来排名
df['排名'] = df['总分'].rank(method='dense',ascending=False).astype('int') df 姓名 班级 语文 数学 英语 总分 平均分 排名 0 赵一 一班 98 96.0 97 291.0 97.00 1 2 张三 一班 86 87.0 93 266.0 88.67 2 3 李四 二班 93 92.0 81 266.0 88.67 2 4 朱五 二班 95 99.0 60 254.0 84.67 3 1 王二 一班 88 90.0 75 253.0 84.33 4
由于这里返回的排名值是一个浮点型,因此需要调用
astype()
方法实现数据类型转换
-
-
数据合并与连接:用于实现对多表的操作
-
数据合并:将同种性质表的不同部分合并在一起,一般不需要考虑公共列
-
分为横向合并和纵向合并两种方式。使用
concat()
方法df a b c 0 10 20 30 1 40 50 60 2 70 80 90 df2 d 0 35 1 65 2 95 ###横向合并 df_concat=pd.concat([df,df2],axis=1) df_concat a b c d 0 10 20 30 35 1 40 50 60 65 2 70 80 90 95 df3 a b c 0 110 120 130 ###纵向合并,使用reset_index()可以帮助我们重置合并后的索引。不然就是 0 1 2 0 df_concat=pd.concat([df,df3],axis=0).reset_index(drop=True) df_concat a b c 0 10 20 30 1 40 50 60 2 70 80 90 3 110 120 130
-
如果想要加入学生信息表的数据
df3 = pd.read_excel("学生信息表.xlsx") df3 姓名 性别 住址 0 王二 男 朝阳 1 李四 女 朝阳 2 朱五 男 海淀 3 黄七 男 海淀 4 赵一 女 朝阳 5 马六 女 海淀 6 张三 男 海淀 pd.concat([df_concat,df3],axis=1) 姓名 班级 语文 数学 英语 姓名 性别 住址 0 赵一 一班 98 96.0 97 王二 男 朝阳 1 王二 一班 88 90.0 75 李四 女 朝阳 2 张三 一班 86 87.0 93 朱五 男 海淀 3 李四 二班 93 92.0 81 黄七 男 海淀 4 朱五 二班 95 99.0 60 赵一 女 朝阳 5 马六 三班 86 90 89 马六 女 海淀 6 黄七 三班 96 88 91 张三 男 海淀 由于concat()方法合并数据依赖索引,当两表的数据顺序不一致时,就会产生这类错误,姓名对不上。 要想规避,以姓名为连接键
-
-
数据连接:将不同性质表连接在一起,一般需要考虑公共列
-
调用merge()方法实现数据连接
pd.merge(left,right,how,on) left:左侧DataFrame对象 right:右侧DataFrame对象 how:数据合并的方式 on:连接键
-
两个数据框
DataFrame
想要进行数据连接,需要依赖某个“公共列”作为连接键,数据连接后的结果受参数how
的影响- how=“left”:左表中的数据都会展示出来,右表会根据连接键将数据连接到左表上,对于不符合条件的数据用
NaN
补充(左连接) - how=“right”:右表中的数据都会展示出来,左表会根据连接键将数据连接到左表上,对于不符合条件的数据用
NaN
补充(右连接) - how=“inner”:参数的默认值,显示左表和右表中连接键都存在的数据(内连接)
- how=“outer”:保留两个表的所有信息(全连接)
df a b c 0 10 20 30 1 40 50 60 2 70 80 90 df2 a d 0 10 35 1 40 65 2 75 95 pd.merge(df,df2,how='left',on='a') a b c d 0 10 20 30 35 1 40 50 60 65 2 70 80 90 NaN pd.merge(df,df2,how='right',on='a') a b c d 0 10 20 30 35 1 40 50 60 65 2 75 NaN NaN 95 pd.merge(df,df2,how='inner',on='a') a b c d 0 10 20 30 35 1 40 50 60 65 pd.merge(df,df2,how='outer',on='a') a b c d 0 10 20 30 35 1 40 50 60 65 2 70 80 90 NaN 3 75 NaN NaN 95
- how=“left”:左表中的数据都会展示出来,右表会根据连接键将数据连接到左表上,对于不符合条件的数据用
-
-
-
数据分组与透视表
-
通过合并和连接得到的大表,一般用于“数据分组”和“数据透视表”的计算
DataFrame.groupby(by).聚合函数 by:分组依据
-
一般分组和聚合是搭配使用的,分组后调用聚合函数完成聚合操作
函数 作用 函数 作用 sum() 求和 median() 求中位数 count() 计数 var() 求方差 mean() 求平均值 std() 求标准差 max() 求最大值 describe() 计算描述性统计量 min() 求最小值 first 第一次出现的值 mode() 求众数 last 最后一次出现的值 -
以班级分组,计算每个班级的学生数量
df_merge = pd.merge(df_concat,df3,how='inner',on='姓名') df_merge 姓名 班级 语文 数学 英语 性别 住址 0 赵一 一班 98 96.0 97 男 朝阳 1 王二 一班 88 90.0 75 女 朝阳 2 张三 一班 86 87.0 93 男 海淀 3 李四 二班 93 92.0 81 男 海淀 4 朱五 二班 95 99.0 60 女 朝阳 5 马六 三班 86 90 89 女 海淀 6 黄七 三班 96 88 91 男 海淀 df_merge.groupby("班级").count() 姓名 语文 数学 英语 性别 住址 班级 一班 3 3 3 3 3 3 二班 2 2 2 2 2 2 三班 2 2 2 2 2 2 df_merge.groupby("班级")['姓名'].count() 班级 一班 3 二班 2 三班 2 Name:姓名,dtype:int64
调用
groupby()
方法并搭配聚合函数count()
,按照班级这列进行分组并对其他列进行计数,统计出每个班级的学生数量,实际上只需要对姓名这列计数就够了。 -
以班级、住址分组
df_merge.groupby(['班级','住址'])['姓名'].count() 班级 住址 一班 朝阳 2 海淀 1 二班 朝阳 1 海淀 1 三班 海淀 2 Name:姓名,dtype:int64
-
以班级分组,计算每个班语文成绩最高的分数
df_merge.group("班级")['语文'].max() 班级 一班 98 二班 96 三班 95 Name:语文,dtype:int64
-
-
数据透视表:pivot_table()可以实现数据透视表
参数 作用 data
相当于Excel中的“选中数据源” index
相当于数据透视表字段中的行 columns
相当于数据透视表字段中的列 values
相当于数据透视表字段中的值 aggfunc
相当于计算类型 margins
相当于结果中的总计 margins_name
相当于修改总计名 fill_value
将缺失值用某个指定值填充 -
以住址为行,班级为列,计算每个班级的学生数量,并统计他们的合计值
pd.pivot_table( df_merge,values="姓名", columns="班级",index="住址", aggfunc="count",fill_value=0, margins_name='合计',margins=True ) 班级 一班 二班 三班 合计 住址 朝阳 2 1 0 3 海淀 1 1 2 4 合计 3 2 2 7
-
-
Excel拆分与合并
-
按条件将Excel文件拆分到不同的工作簿
import pandas as pd df = pd.read_excel("三年级总成绩单.xlsx") for i in df['班级'].unique(): df[df['班级']==i].to_excel(f"{i}.xlsx",index=False)
-
按条件将Excel拆分到不同的工作表
import pandas as pd df = pd.read_excel("三年级总成绩单.xlsx") for i in df['班级'].unique(): df[df['班级']==i].to_excel( "三年级总成绩单.xlsx",index=False,sheet_name=f"{i}" )
但是执行后发现每次生成的工作表都会覆盖前一个,最终只剩下一个表,用这个方法实现
import pandas as pd df = pd.read_excel('三年级总成绩单.xlsx') writer = pd.ExcekWriter("三年级总成绩单.xlsx") df.to_excel(writer,sheet_name='总成绩',index=False) for j in df['班级'].unique(): df[df['班级']==j].to_excel(writer,sheet_name=j,index=False)
ExcelWriter()
方法,他会帮助我们建立一个空的容器对象writer
-
-
批量将不同的工作表合并到一个excel文件
import pandas as pd sheet_names = pd.ExcelFile("三年级分班成绩单.xlsx").sheet_names df_all = pd.DataFrame() for i in sheet_names: df = pd.read_excel("三年级分班成绩单.xlsx",sheet_name=i) df_all = df_all.append(df) df_all.to_excel( '三年级分班成绩单.xlsx',sheet_name='总成绩' )
ExcelFile()
会得到一个ExcelFile
对象。该对象有一个很好用的sheet_names属性,它能够获取当前表格中所有工作表的名称,并以一个列表返回