🤵♂️ 个人主页:@艾派森的个人主页
✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+
目录
Pandas是什么
Series对象创建
DataFrame对象创建
导入Excel文件
导入csv文件
导入txt文件
读取数据库数据
保存数据
保存数据至外部文件
保存数据至数据库
了解数据
列操作
修改变量列
筛选变量列
删除变量列
添加变量列
变量类型的转换
建立索引
引用和修改索引
Series的索引和切片
DataFrame的索引和切片
排序
计算新变量
修改替换变量值
数值变量分段
数据分组
分组汇总
多个数据源的合并
数据的纵向合并
数据的横向合并
concat 命令
处理缺失值
删除缺失值
数据查重
日期时间变量
数据交叉表
数据的图形展示
Pandas是什么
Pandas 包 是基于 Python 平台的数据管理利器,已经成为了 Python 进行数据分析和挖掘 时的数据基础平台和事实上的工业标准。 使用 Pandas 包完成数据读入、数据清理、数据准备、图表呈现等 工作,为继续学习数据建模和数据挖掘打下坚实基础。
安装
pip install pandas
Series对象创建
Series:一维数组,与Numpy中的一维array类似。它是一种类似于 一维数组的对象,是由一组数据(各种 NumPy 数据类型)以及一组与 之相关的数据标签(即索引)组成。仅由一组数据也可产生简单的 Series 对象。用值列表生成 Series 时,Pandas 默认自动生成整数 索引 。
pandas中两个重要的属性 values 和index,values:是Series对象的 原始数据。index:对应了Series对象的索引对象
DataFrame对象创建
DataFrame 是 Pandas 中的一个表格型的数据结构,包含有一组有 序的列,每列可以是不 同的值类型(数值、字符串、布尔型等),DataFrame 即有行索引也 有列索引,可以被看做是由 Series 组成的字典。 将两个series对象作为dict的value传入,就可以创建一个 DataFrame对象。
导入Excel文件
使用read_excel()方法导入文件,首先要指定文件的路径。
说明 :使用Pandas模块操作Excel时候,需要安装openpyxl
import pandas as pd
pd.read_excel('stu_data.xlsx')
导入.xlsx文件时,指定导入哪个Sheet
pd.read_excel('stu_data.xlsx',sheet_name='Target')
pd.read_excel('stu_data.xlsx',sheet_name=0)
导入.xlsx文件时,通过index_col指定行索引
pd.read_excel('stu_data.xlsx',sheet_name=0,index_col=0)
导入.xlsx文件时,通过header指定列索引
pd.read_excel('stu_data.xlsx',sheet_name=0,header=1)
有时候本地文件的列数太多,而我们又不需要那么多列时,我们就 可以通过设置usecols参数来指定要导入的列。
pd.read_excel('stu_data.xlsx',usecols=[1,2,3])
导入csv文件
导入csv文件时除了指明文件路径,还需要设置编码格式。Python 中用得比较多的两种编码格式是UTF-8和gbk,默认编码格式是UTF-8。我们要根据导入文件本身的编码格式进行设置,通过设置参数 encoding来设置导入的编码格式。
导入.csv文件,文件编码格式是gbk
pd.read_csv('stu_data.csv',encoding='gbk')
导入.csv文件,指明分隔符
pd.read_csv("stu_data.csv",encoding='gbk',sep=' ')
pd.read_csv('stu_data.csv',encoding='gbk',sep=',')
导入txt文件
导入.txt文件用得方法时read_table(),read_table()是将利用分隔符 分开的文件导入。DataFrame的通用函数。它不仅仅可以导入.txt 文件,还可以导入.csv文件。
导入.txt文件
pd.read_table('test_data.txt',encoding='utf8',sep='\t')
导入.csv文件,指明分隔符
pd.read_table('stu_data.csv',encoding='gbk',sep=',')
读取数据库数据
配置 MySQL 连接引擎:
conn = pymysql.connect(
host = 'localhost',
user = 'root',
passwd = 'root',
db = 'mydb',
port=3306,
charset = 'utf8' )
读取数据表:
pd.read_sql(
sql :需要执行的 SQL 语句/要读入的表名称
con : 连接引擎名称
index_col = None :将被用作索引的列名称
columns = None :当提供表名称时,需要读入的列名称
list
)
tab1 = pd.read_sql('select * from
emp',con=conn)
tab1 = pd.read_sql('select count(*) from
emp',con=conn)
保存数据
保存数据至外部文件
df.to_csv(
filepath_or_buffer :要保存的文件路径
sep =:分隔符
columns :需要导出的变量列表
header = True :指定导出数据的新变量名,可直接
提供 list
index = True :是否导出索引
mode = 'w' : Python 写模式,读写方式:r,r+ ,
w , w+ , a , a+ encoding = 'utf-8' :默认
导出的文件编码格式
)
df.to_excel(
filepath_or_buffer :要读入的文件路径
sheet_name = 1 Sheetl1 :要保存的表单名称
)
保存数据至数据库
df.to_sql(
name :将要存储数据的表名称
con : 连接引擎名称
if_exists = 'fail' :指定表已经存在时的处理方
式
fail :不做任何处理(不插入新数据)
replace :删除原表并重建新表
append :在原表后插入新数据
index = True :是否导出索引 )
#pip install sqlalchemy
from sqlalchemy import create_engine
con =
create_engine('mysql+pymysql://root:root@loc
alhost:3306/mydb?charset=utf8')
df.to_sql('t_stu',con,if_exists=append)
了解数据
head()与 tail()
head()方法返回前 n 行(观察索引值),显示元素的数量默认是 5,但 可以传递自定义数值
tail()方法返回后 n 行观察索引值),显示元素的数量默认是 5,但可 以传递自定义数值
#浏览前几条记录
df.head()
df.head(10)
#浏览最后几条记录
df.tail()
info()
info()方法查看数据表中的数据类型,而且不需要一列一列的查看, info()可以输出整个表 中所有列的数据类型。
df.info()
shape
shape()方法会以元组的形式返回行、列数。注意 shape 方法获取 行数和列数时不会把索 引和列索引计算在内。
df.shape
describe()
describe()方法就是可以就可以获取所有数值类型字段的分布值。
df.describe()
列操作
修改变量列
columns
df.columns =新的名称 list
rename()
df.rename(
columns =新旧名称字典:{旧名称,:新名称,}
inplace = False :是否直接替换原数据框)
df.rename(columns =
{'newname':'name','newname2':'name2'},
inplace = True )
筛选变量列
通过 df.var 或 df[var] 可以选择单列
注意: 但只适用于已存在的列,只能筛选单列,结果为 Series
df[[var]] 单列的筛选结果为 DataFream
df[['var1', 'var2']] 多列时,列名需要用列表形式提
供(因此可使用列表中的切片操作) 多列的筛选结果为 DF
删除变量列
df.drop(
index / columns =准备删除的行/列标签,多个时用列表
形式提供
inplace = False :是否直接更改原数据框 )
df.drop(columns =['col1','col2'])
del df['column-name'] 直接删除原数据框相应的一列,
建议尽量少用
del df.column_name #不允许
添加变量列
根据新数据添加
df[cloumn] = pd.Series([val,val2,val3],index=[c1,c2,c3])
根据原数据添加
df[cloumn] = df[c2]+df[c3]
变量类型的转换
Pandas 支持的数据类型
具体类型是 Python, Numpy 各种类型的混合,可以比下表分的更细
float int string bool datetime64[nsr] datetime64[nsr,tz] timedelta[ns] category object
df.dtypes :査看各列的数据类型
在不同数据类型间转换
df.astype(
dtype :指定希望转换的数据类型,可以使用 numpy 或
者 python 中的数据类型: int/float/bool/str
copy = True :是否生成新的副本,而不是替换原数据框
errors = 'raise' : 转换出错时是否抛出错误,
raise/ ignore )
#将df里所有的列转换成str
df.astype('str')
df.astype('str').dtypes
#修改某一列数据的数据类型
df.column.astype ('str')
#转换错误
df.astype('int', errors = 'ignore').dtypes 明
确指定转换类型的函数
旧版本方法:
pd.to_datetime ()
pd.to_timedelta ()
pd.to_numeric ()
pd.to_string()
建立索引
新建数据框时建立索引
所有的数据框默认都已经使用从 0 开始的自然数索引,因此这里 的"建立”索引指的是自定义索引
df = pd.DataFrame( {'varl' : 1.0, ' var2' :
[1,2,3,4], 'var3' : ['test', 'python','test',
'hello'] , 'var4' : 'cons'} , index =
[0,1,2,3]
)
读入数据时建立索引
使用现有的列
df = pd.read_csv ("filename",index_col="column”)
使用复合列
df = pd.read_csv ("filename", index_col=[0,1..])
指定某列为索引列
df.set_index(
keys :被指定为索引的列名,复合索引用 list:格式
提供
drop = True :建立索引后是否删除该列
append = False :是否在原索引基础上添加索引,默
认是直接替换原索引 inplace = False :是否直
接修改原数据框 )
df_new = df.set_index (keys=['学号','性别'],drop = False)
df_new = df.set_index (keys='学号',append=True, drop=False)
将索引还原变量列
df.reset_index(
drop = False :是否将原索引直接删除,而不是还原为变量列
inplace = False :是否直接修改原数据框)
引用和修改索引
引用索引
注意: 索引仍然是有存储格式的,注意区分数值型和字符型的引用方式
df.index
修改索引
修改索引名
本质上和变量列名的修改方式相同
df = pd.DataFrame({
'name':['zs','ls','ww'],
'level':['vip1','vip2','pm']
})
df.index.name='sno'
修改索引值
这里的修改本质上是全部替换
df1.index = ['a', 'b', 'c']
更新索引
reindex 则可以使用数据框中不存在的数值建立索引,并据此扩充 新索引值对应的索引行/ 列,同时进行缺失值填充操作。
df.reindex(labels :类数组结构的数值,将按此数值重建索引,非必需
copy = True :建立新对象而不是直接更改原 df/series 缺失数
据的处理方式
method :针对已经排序过的索引,确定数据单元格无数据时
的填充方法,非必需
pad / ffill:用前面的有效数值填充
backfill / bfill:用后面的有效数值填充
nearest:使用最接近的数值逬行填充
fill_value = np.NaN :将缺失值用什么数值替代
limit = None :向前/向后填充时的最大步长
)
import pandas as pd
df = pd.DataFrame({
'name':['zs','ls','ww'],
'level':['vip1','vip2','pm']
})
df.reindex([0,1,3])
df.reindex([0,1,2,3],method='ffill')
df.reindex([0,1,2,3],fill_value="test")
Series的索引和切片
索引
import numpy as np
import pandas as pd
data=pd.Series([4,3,25,2,3],index=list('abcde'))
data['a'] #根据key获取
data[1] #索引获取
data[-1]
切片
import numpy as np
import pandas as pd
data=pd.Series([4,3,25,2,3],index=list('abcde'))
data['a':'d']
data[2:4] #索引切片
data[-3:-1]
data[data>3]
如果索引与行名相同都是1,这时候就不知道是按照哪个来获取,所 以获取时候使用loc、iloc
loc函数:通过行索引 "Index" 中的具体值来取行数据及根据普通索 引获取。(如取"Index"为"A"的行)
iloc函数:通过行号来取行数据,及根据位置索引获取。
data=pd.Series([5,3,2,5,9],index=[1,2,3,4,5])
data.loc[1]
data.iloc[1]
DataFrame的索引和切片
选择列
当想要获取 df 中某列数据时,只需要在 df 后面的方括号中指明要 选择的列即可。如果是 一列,则只需要传入一个列名;如果是同时选择多列,则传入多个列 名即可(注意:多个列名 用一个 list 存放)
#获取一列
df[col]
#获取多列
df[[col1 , col2]]
除了传入具体的列名,我们可以传入具体列的位置,即第几行,对 数据进行选取,通过传 入位置来获取数据时需要用到 iloc 方法。
df.iloc[,[0,2]]
按行列索引选择
DataFrame对象按照行列检索获取,可以使用loc和iloc函数,方括 号中逗号之前的部分表示要获取的行的索引,如果输入一个冒号, 或不输入任何数值表示获取所有的行或列,逗号之后方括号表示要 获取的列的索引。
df.loc[普通行索引,普通列索引]
df.iloc[位置行索引,位置列索引]
isin()选择
df.isin(values) 返回结果为相应的位置是否匹配给出的 values
values 为序列:对应每个具体值
values 为字典:对应各个变量名称
values 为数据框:同时对应数值和变量名称
df.col.isin([1,3,5])
df[ df.col.isin([1,3,5])]
df[ df.col.isin(['val1','val2'])]
df[ df.index.isin(['val1','val2'])]
query()的使用
使用boolean值表达式进行筛选
df.query(
expr:语句表达式
inplace=False;是否直接替换原数据框
)
可以使用前缀“@”引用环境变量 等号为==,而不是=
df.query("col>10 and col<90 and col1=val")
limit = 5
df.query("col<=@limit & col==val")
df.query("col<=@limit & col!=val")
排序
用索引排序
df.sort_index(
level :(多重索引时)指定用于排序的级别顺序号/名称18
ascending = True :是否为升序排列,多列时以表形式提供
inplace = False :
na_position = 'last‘ :缺失值的排列顺序,
first/last
)
df = pd.read_excel("stu_data.xlsx",
index_col=["学号”,”性别”]) df.set_index( ['学号','性别'], inplace = True )
# 通过索引进行排序
df.sort_index()
df.sort_index(ascending = [True,False])
#设置哪个索引进行排序
df.sort_index(level="支出")
df.sort_index(level= ["支出","体重"])
使用变量值排序
df.sort_values(
by :指定用于排序的变量名,多列时以列表形式提供
ascending = True :是否为升序排列
inplace = False )
# 根据值进行排序
df.sort_values(by='身高')
计算新变量
新变量为常数
df['vamame'] = value
基于原变量做简单四则运算
df['var'] = df['oldvar'] *100
df['var'] = df.oldvar * 100
基于一个原变量做函数运算
df.apply(
func : 希望对行/列执行的函数表达式
axis = 0 :针对行还是列逬行计算
0 ' index':针对每列进行计算
1' columns ':针对每行逬行计算
)
简化的用法
df [' varname ' ] = df. oldvar. apply (函数表达式)
df['n5'] = df.体重.apply(math.sqrt)
df['n7'] = df.体重.apply(numpy.sqrt)
不修改原df,而是生成新的df
df.assign(varname = expression)
在指定位置插入新变量列
df.insert(
loc :插入位置的索引值,0 <= loc <= len (columns)
column :插入的新列名称
value : Series 或者类数组结构的变量值
allow_duplicates = False :是否允许新列重名
)
#该方法会直接修改原 df
# 指定位置增加新列
df.insert(1,'new_col',100)
df.insert(1,'new_col2',df.课
程.apply(get_first))
修改替换变量值
本质上是如何直接指定单元格的问题,只要能准确定位单元地址, 就能够做到准确替换。
对应数值的替换
df.replace(
to_replace = None :将被替换的原数值,所有严格匹配的数值
将被用 value 替换,可以
str/regex/list/dict/Series/numeric/None
value = None :希望填充的新数值
inplace = False
)
指定数值范围的替换
方法一:使用正则表达式完成替换
df.replace(regex, newvalue)
方法二:使用行筛选方式完成替换 用行筛选方式得到行索引,然后用 loc 命令定位替换 目前也支持直接筛选出单元格进行数值替换
注意: query 命令的类 SQL 语句可以逬行检索,但不直接支持数值替换
# 使用正则匹配数据
df.开设.replace(regex = '不.+',value = '可以',inplace = True)
#iloc loc
df.支出.iloc[0:3] = 20
df.支出.loc[0:2] =30
#条件筛选替换
df.体重[df.体重>70] =70
df[df.体重==70].体重 = 80 # 注意引用问题
#query()的使用
df.query('性别 == "女" and 体重 > 60 ').体重 =50
df.loc[df.query('性别 == "女" and 体重 > 60').体重.index,'体重'] = 50
数值变量分段
pd.cut(
X :希望逬行分段的变量列名称
bins :具体的分段设定
int :被等距等分的段数
sequence of scalars :具体的每一个分段起点,必须包括最值,可不等距
right = True :每段是否包括右侧界值
labels = None :为每个分段提供自定义标签
include_lowest = False :第一段是否包括最左侧界值,需要和
right 参数配合
)
#分段结果是数值类型为 Categories 的序列
pd.qcut # 按均值取值范围进行等分
#按均值取值范围进行等分
df['cut1'] = pd.qcut(df.身高,q=5)
#自定义分段
df['cut2'] = pd.cut(df.身高,bins=[150,160,170,180,190],right=False)
数据分组
df.groupby(
by :用于分组的变量名/函数
level = None :相应的轴存在多重索引时,指定用于分组的级别
as_index = True :在结果中将组标签作为索引
sort = True :结果是否按照分组关键字逬行排序
)#生成的是分组索引标记,而不是新的 df
基于拆分进行筛选
筛选出其中一组 dfgroup.get_group()
dfg.get_group ('不必要').mean ()
dfg.get_group ('不必要').std ()
筛选出所需的列
该操作也适用于希望对不同的变量列进行不同操作时
分组汇总
在使用 groupby 完成数据分组后,就可以按照需求进行分组信息汇 总,此时可以使用其 它专门的汇总命令,如 agg 来完成汇总操作。
使用 agg 函数进行汇总
df.aggregate( ) 名称可以直接简写为 agg
dfg.agg( 'count')
dfg.agg('median')
dfg.agg(['mean', 'median'])
dfg.agg(['mean', 'median'])
#引用非内置函数
import numpy as np
df2.身高.agg (np. sum)
dfg.身高.agg (np. sum)
多个数据源的合并
数据的纵向合并
df.append(
other :希望添加的 DF/Series/字典/上述对象的列表使用列表方式,就可以实现一次合并多个新对象
ignore_index = False :添加时是否忽略索引
verify_integrity = False :是否检查索引值的唯一性,有重复时报错
)
df = df.append( [df2, df3, df4])
数据的横向合并
merge 命令使用像 SQL 的连接方式
pd.merge(
需要合并的 DF
left :需要合并的左侧 DF
right :需要合并的右侧 DF
how = ' inner':具体的连接类型
{left、right 、outer 、 inner、)
两个 DF 的连接方式
on :用于连接两个 DF 的关键变量(多个时为列表),必须在两侧都出现
left_on :左侧 DF 用于连接的关键变量(多个时为列表)
right_on :右侧 DF 用于连接的关键变量(多个时为列表)
left_index = False :是否将左侧 DF 的索引用于连接
right_index = False :是否将右侧 DF 的索引用于连接
)
concat 命令
同时支持横向合并与纵向合并
pd.concat(
objs :需要合并的对象,列表形式提供
axis = 0 :对行还是对列方向逬行合并
(0 index 、 1 columns )
join = outer :对另一个轴向的索引值如何逬行处理
(inner 、outer )
ignore_index = False
keys = None :为不同数据源的提供合并后的索引值
verify_integrity = False 是否检查索引值的唯一性,有重复时报错
copy = True
)
ser1=pd.Series([1,2,3],index=list('ABC'))
ser2=pd.Series([4,5,6],index=list('DEF'))
pd.concat([ser1,ser2])
处理缺失值
认识缺失值
系统默认的缺失值 None 和 np. nan
缺失值查看
直接调用info()方法就会返回每一列的缺失情况。
Pandas中缺失值用NaN表示,从用info()方法的结果来看,索引1这 一列是1 2 non-null float64,表示这一列有2个非空值,而应该是 3个非空值,说明这一列有1个空值。 还可以用isnull()方法来判断哪个值是缺失值,如果是缺失值则返回 True,如果不是缺失值返回False。 df.isna(): 检查相应的数据是否为缺失值 同 df.isnull()。 df.notna()等同于notnull()
检查多个单元格的取值是否为指定缺值
df.any(
axis : index (0), columns (1)
skipna = True :检查时是否忽略缺失值
level = None :多重索引时指定具体的级别
)
df.all(
axis : index (0), columns (1)
skipna = True :检查时是否忽略缺失值
level = None :多重索引时指定具体的级别
)
填充缺失值
调用fillna()方法对数据表中的所有缺失值进行填充,在fillna()方法 中输入要填充的值。还可以通过method参数使用前一个数和后一 个数来进行填充。
df.fillna(
value :用于填充缺失值的数值,也可以提供dict/Series/DataFrame 以进—步指明哪些索引/列会被替换不能使用 list
method = None :有索引时具体的填充方法,向前填充,向后填充等
limit = None :指定了 method 后设定具体的最大填充步长,此步长不能填充
axis : index (0), columns (1)
inplace = False
)
data=pd.Series([3,4,np.nan,1,5,None])
print('以0进行填充:')
print(data.fillna(0))
print('以前一个数进行填充:')
print(data.fillna(method='ffill'))
print('以后一个数进行填充:')
print(data.fillna(method='bfill'))
print('先按前一个,再按后一个')
print(data.fillna(method='bfill').fillna(method='ffill'))
删除缺失值
调用dropna()方法删除缺失值,dropna()方法默认删除含有缺失值 的行,也就是只要某一行有缺失值就把这一行删除。如果想按列为 单位删除缺失值,需要传入参数axis=’columns’。
df.dropna(
axis = 0 : index (0), columns (1)
how = any : any、all
any :任何一个为 NA 就删除
all :所有的都是 NA 删除
thresh = None :删除的数量阈值,int
subset :希望在处理中包括的行/列子集
inplace = False :
)
df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
print('默认为以行为单位剔除:')
print(df.dropna())
print('以列为单位剔除:')
df.dropna(axis='columns')
数据查重
标识出重复的行
标识出重复行的意义在于进一步检査重复原因,以便将可能的错误 数据加以修改
Duplicated
df['dup' ] = df.duplicated( ['课程','开设'])
利用索引进行重复行标识 df.index.duplicated()
df2 = df.set_index ( ['课程','开设'] )
df2.index.duplicated ()
直接删除重复的行
drop_duplicates (
subset=“ ”按照指定的行逬行去重
keep='first' 、 'last' 、 False 是否直接删除有重复的所有记录
)
df. drop_duplicates ( ['课程', '开设' ] )
df. drop_duplicates ( ['课程', ‘开设' ] , keep= False )
日期时间变量
Timestamp
from datetime import datetime
pd.Timestamp(datetime(2032,1,1))
pd.Timestamp(datetime(2032,1,2,3,4,5))
pd.Timestamp(2032,1,2)
pd.Timestamp('2032-01-02 3:4:5')
Peroid
可以被看作是简化之后的 Timestamp 对象
由于详细数据的不完整,而表示的是一段时间,而不是一个时点 但是实际使用中很可能是按照时点在使用 很多使用方法和 Timestamp 相同,因此不再详细介绍
pd.Period('2032-01')
pd.Period('2032-01',freq='D')#精确到日
数据交叉表
df.pivot_table(
行列设定
index / columns :行变量/列变量,多个时以list 形式提供
单元格设定
values :在单元格中需要汇总的变量列,可不写
aggfunc = numpy.mean : 相应的汇总函数
汇总设定
margins = False :是否加入行列汇总
margins_name = 'All':汇总行/列的名称
缺失值处理
fill_value = None :用于替换缺失值的数值
dropna = True
)
pd.crosstab(
选项和 pivot_table 几乎相同
相对而言需要打更多字母,因此使用更麻烦
但是计算频数最方便
输出格式为数据框 )
df.pivot_table(index = ['课程','性别'],
columns='开设',values = ['体重','身高'],aggfunc='sum')
pd.crosstab(index=[df.课程],columns=df.开设,values=df.体重,aggfunc=sum)
数据的图形展示
df.plot(
绘图用数据
data :数据框
x = None:行变量的名称/顺序号
y = None :列变量的名称/顺序号
kind = 'line':需要绘制的图形种类
line : line plot (default)
bar : vertical bar plot
barh : horizontal bar plot
hist : histogram
box : boxplot
kde : Kernel Density Estimation plot
density : same as kde
area : area plot
pie : pie plot
scatter : scatter plot
hexbin : hexbin plot
各种辅助命令
figsize : a tuple (width, height) in inches
xlim / ylim : X/Y 轴的取值范围,2-tuple/list 格式
logx / logy / loglog = False :对 X/Y/双轴同时使用对数尺度
title : string or list
Alpha :图形透明度,0-1
图组命令
subplots = False :是否分图组绘制图形
sharex :是否使用相同的 X 坐标
ax = None 时,取值为 True,否则取值为 False
sharey = False :是否使用相同的 Y 坐标
ax = None :需要叠加的 matplotlib 绘图对象
图形种类的等价写法 df.plot.kind()
配置绘图系统环境
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #
指定默认字体 SimHei为黑体
plt.figure ()
import seaborn as sns
sns.set_style('whitegrid')
pd.value_counts(df.课程).plot.bar()
pd.value_counts(df.课程).plot(kind='bar')
pd.value_counts(df.课程).plot.barh()
整理不易,希望对学习Pandas的小伙伴有所帮助!