Pandas统计分析基础:画图美观性及基于数据透视表的数据分析
Posted Xlong~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pandas统计分析基础:画图美观性及基于数据透视表的数据分析相关的知识,希望对你有一定的参考价值。
✅作者简介:大家好我是Xlong,一枚正在学习COMSOL、Python的工科研究僧
📃个人主页: Xlong的个人博客主页
🔥系列专栏: Python大数据分析
💖如果觉得博主的文章还不错的话,请👍支持一下博主哦🤞
目录
一、 画图的美观性
做数据分析,图、表、文字是展示分析结果时使用的三种手段。其中,图最为直观,也是读者/观众最容易接收的信息。因此,图的合理、准确、美观是数据分析工作中最重要的部分之一。
比如在学术论文里,越是水平高的学术期刊,发表的论文里图就画的越漂亮。
该网站内有pandas.DataFrame.plot()所包含的所有可调参数,可以尝试使用
pandas.DataFrame.plot — pandas 1.4.1 documentation
import pandas as pd
df=pd.read_excel('GDP.xlsx',index_col=0)
print(df.head())
运行结果:
第三产业增加值 地区生产总值
北京市 24553.64 30319.98
天津市 11027.12 18809.64
河北省 16632.21 36010.27
山西省 8988.28 16818.11
内蒙古自治区 8728.10 17289.22
数据分析第一步:画个图看看
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
df=pd.read_excel('GDP.xlsx',index_col=0)
df.plot()
plt.show()
运行结果:
数据分析第二步:尝试建立一些指标,并且画个图看看是否恰当
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
df=pd.read_excel('GDP.xlsx',index_col=0)
df['第三产业对GDP贡献率']=df['第三产业增加值']/df['地区生产总值']
print(df.head())
运行结果:
第三产业增加值 地区生产总值 第三产业对GDP贡献率
北京市 24553.64 30319.98 0.809817
天津市 11027.12 18809.64 0.586248
河北省 16632.21 36010.27 0.461874
山西省 8988.28 16818.11 0.534441
内蒙古自治区 8728.10 17289.22 0.504829
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
df=pd.read_excel('GDP.xlsx',index_col=0)
df['第三产业对GDP贡献率']=df['第三产业增加值']/df['地区生产总值']
df.plot()
plt.show()
由于量级不同,因此需要分开画
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
df=pd.read_excel('GDP.xlsx',index_col=0)
df['第三产业对GDP贡献率']=df['第三产业增加值']/df['地区生产总值']
df.plot(subplots=True,layout=(1,3)) #dataframe.plot()可以添加layout参数来修改子图的布局
plt.show()
由于第三产业增加值、地区生产总值、第三产业对GDP贡献率三者是共线的,因此保留两个即可。
我们把GDP和贡献率画到一起。需要使用副坐标轴。
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
df=pd.read_excel('GDP.xlsx',index_col=0)
df['第三产业对GDP贡献率']=df['第三产业增加值']/df['地区生产总值']
df[['地区生产总值','第三产业对GDP贡献率']].plot(secondary_y=['第三产业对GDP贡献率']) #dataframe也能画副坐标轴
plt.show()
matplotlib里提供了一些画图的style模板,通过plt.style.use()调用。可以很方便的使图变得好看。
官方给出了所有模板的名称,可以自选使用:
Style sheets reference — Matplotlib 3.5.1 documentation
示例:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
df=pd.read_excel('GDP.xlsx',index_col=0)
df['第三产业对GDP贡献率']=df['第三产业增加值']/df['地区生产总值']
plt.style.use('ggplot') #该命令需要用在新建画布和子图之前,才能生效
fig1,ax1=plt.subplots(figsize=(10,6))
df[['地区生产总值','第三产业对GDP贡献率']].plot(ax=ax1,secondary_y=['第三产业对GDP贡献率'])
ax1.set_xticks(np.arange(len(df.index)))
ax1.set_xticklabels(df.index,rotation=90)
ax1.set_ylabel('GDP(亿元)')
ax1.right_ax.set_ylabel('第三产业占比')
plt.show()#fig1.show()命令也可以
此外,python还有很多作图包可以很简单的画出漂亮的图。如seaborn。seaborn: statistical data visualization — seaborn 0.11.2 documentation
二、基于数据透视表的数据分析
运用透视表功能进行分析 pandas.pivot_table()
案例:上篇文章用到的数据
import pandas as pd
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
print(gdpandpop.head())
运行结果:
GDP POP CapitalGDP REGION
省份
北京市 30319.98 2154 14.076128 华北
天津市 18809.64 1560 12.057462 华北
河北省 36010.27 7556 4.765785 华北
山西省 16818.11 3718 4.523429 华北
内蒙古自治
import pandas as pd
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
print(gdpandpop.describe())
运行结果:
GDP POP CapitalGDP
count 31.000000 31.000000 31.000000
mean 29506.692258 4504.935484 6.508875
std 23905.147349 2891.081054 2.914103
min 1477.630000 344.000000 3.127065
25% 15718.120000 2510.500000 4.737428
50% 21984.780000 3864.000000 5.279864
75% 36218.025000 6120.500000 7.217045
max 97277.770000 11346.000000 14.076128
按人口数量简单分类,以四分之一分位值分割,分为特大、大、中、小四档
import pandas as pd
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
print(gdpandpop)
运行结果:
GDP POP CapitalGDP REGION 人口规模
省份
北京市 30319.98 2154 14.076128 华北 小
天津市 18809.64 1560 12.057462 华北 小
河北省 36010.27 7556 4.765785 华北 特大
山西省 16818.11 3718 4.523429 华北 中
内蒙古自治区 17289.22 2534 6.822897 华北 中
辽宁省 25315.35 4359 5.807605 东北 大
吉林省 15074.62 2704 5.574933 东北 中
黑龙江省 16361.62 3773 4.336501 东北 中
上海市 32679.87 2424 13.481795 华东 小
江苏省 92595.40 8051 11.501105 华东 特大
浙江省 56197.15 5737 9.795564 华东 大
安徽省 30006.82 6324 4.744911 华东 特大
福建省 35804.04 3941 9.085014 华东 大
江西省 21984.78 4648 4.729944 华东 大
山东省 76469.67 10047 7.611194 华东 特大
河南省 48055.86 9605 5.003213 中南 特大
湖北省 39366.55 5917 6.653127 中南 大
湖南省 36425.78 6899 5.279864 中南 特大
广东省 97277.77 11346 8.573750 中南 特大
广西壮族自治区 20352.51 4926 4.131650 中南 大
海南省 4832.05 934 5.173501 中南 小
重庆市 20363.19 3102 6.564536 西南 中
四川省 40678.13 8341 4.876889 西南 特大
贵州省 14806.45 3600 4.112903 西南 中
云南省 17881.12 4830 3.702095 西南 大
西藏自治区 1477.63 344 4.295436 西南 小
陕西省 24438.32 3864 6.324617 西北 大
甘肃省 8246.07 2637 3.127065 西北 中
青海省 2865.23 603 4.751625 西北 小
宁夏回族自治区 3705.18 688 5.385436 西北 小
新疆维吾尔自治区 12199.08 2487 4.905139 西北 小
import pandas as pd
import numpy as np
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
pt1=pd.pivot_table(gdpandpop,values='CapitalGDP',index='REGION',aggfunc=np.mean)
#默认的聚合函数为求均值,aggfunc=np.mean可以省略,不影响结果
print(pt1)
运行结果:
CapitalGDP
REGION
东北 5.239680
中南 5.802517
华东 8.707075
华北 8.449140
西北 4.898776
西南 4.710372
import pandas as pd
import numpy as np
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
pt2=pd.pivot_table(gdpandpop,values='CapitalGDP',index='REGION',columns='人口规模',aggfunc=np.mean)
print(pt2)
运行结果:
人口规模 中 大 小 特大
REGION
东北 4.955717 5.807605 NaN NaN
中南 NaN 5.392389 5.173501 6.285609
华东 NaN 7.870174 13.481795 7.952404
华北 5.673163 NaN 13.066795 4.765785
西北 3.127065 6.324617 5.014067 NaN
西南 5.338719 3.702095 4.295436 4.876889
透视表有一个重要功能,通过margins=True开启边缘值计算。
import pandas as pd
import numpy as np
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
pt3=pd.pivot_table(gdpandpop,values='CapitalGDP',index='REGION',columns='人口规模',aggfunc=np.mean,margins=True)
print(pt3)
运行结果:
人口规模 中 大 小 特大 All
REGION
东北 4.955717 5.807605 NaN NaN 5.239680
中南 NaN 5.392389 5.173501 6.285609 5.802517
华东 NaN 7.870174 13.481795 7.952404 8.707075
华北 5.673163 NaN 13.066795 4.765785 8.449140
西北 3.127065 6.324617 5.014067 NaN 4.898776
西南 5.338719 3.702095 4.295436 4.876889 4.710372
All 5.008895 6.278702 8.015815 6.544589 6.508875
来比较一下透视表和上篇文章中的groupby之间的差异
import pandas as pd
import numpy as np
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
gb=gdpandpop.groupby(by=['REGION','人口规模'])['CapitalGDP'].apply(np.mean)
print(gb)
运行结果:
REGION 人口规模
东北 中 4.955717
大 5.807605
中南 大 5.392389
小 5.173501
特大 6.285609
华东 大 7.870174
小 13.481795
特大 7.952404
华北 中 5.673163
小 13.066795
特大 4.765785
西北 中 3.127065
大 6.324617
小 5.014067
西南 中 5.338719
大 3.702095
小 4.295436
特大 4.876889
Name: CapitalGDP, dtype: float64
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
gb=gdpandpop.groupby(by=['REGION','人口规模'])['CapitalGDP'].apply(np.mean)
plt.style.use('grayscale')
fig,axes=plt.subplots(1,2) #这样生成的axes是多个子图构成的数组,调用时要以axes[0],axes[1]这样的形式调用每个子图对象
print(type(axes))
print(axes.shape)
pt2=pd.pivot_table(gdpandpop,values='CapitalGDP',index='REGION',columns='人口规模',aggfunc=np.mean)
pt2.plot.bar(ax=axes[0])
gb.plot.bar(ax=axes[1])
plt.show()
运行结果:
<class 'numpy.ndarray'>
(2,)
两者在数据的统计、聚合功能上没有显著区别.但在显示模式(包括直观显示和默认画图)上的差别,数据透视表在显示上更友好一些。
这也是由他们生成的DataFrame的维度决定的,数据透视表通过values这个属性降低了一个维度(行名+列名的总数要比对应的groupby方法少一个)。
P.S. 有一种特殊的专用于计算频数的透视表,叫做交叉表pandas.crosstab()
使用pivot_table的实现方式,可以使用python自带的len()函数来计数。
import pandas as pd
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
pt4=pd.pivot_table(gdpandpop,values='CapitalGDP',index='REGION',columns='人口规模',aggfunc=len)
print(pt4)
运行结果:
人口规模 中 大 小 特大
REGION
东北 2.0 1.0 NaN NaN
中南 NaN 2.0 1.0 3.0
华东 NaN 3.0 1.0 3.0
华北 2.0 NaN 2.0 1.0
西北 1.0 1.0 3.0 NaN
西南 2.0 1.0 1.0 1.0
使用crosstab的实现方式,使用默认设置即可。相对简洁一些
import pandas as pd
gdpandpop=pd.read_excel('GDPandPopulation.xlsx',index_col=0)
#定义一个函数,用于判定人口规模
def popsize(x):
if x>=6120.5:
return '特大'
elif x>=3864.0:
return '大'
elif x>=2510.5:
return '中'
else:
return '小'
gdpandpop['人口规模']=gdpandpop['POP'].apply(popsize)
ct=pd.crosstab(gdpandpop['REGION'],gdpandpop['人口规模'])
print(ct)
运行结果:
人口规模 中 大 小 特大
REGION
东北 2 1 0 0
中南 0 2 1 3
华东 0 3 1 3
华北 2 0 2 1
西北 1 1 3 0
西南 2 1 1 1
以上就是《Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析》,如果有改进的建议,欢迎在评论区留言交流~
持续更新中......原创不易,各位看官请随手点下Follow和Star,感谢!!!
以上是关于Pandas统计分析基础:画图美观性及基于数据透视表的数据分析的主要内容,如果未能解决你的问题,请参考以下文章
Pandas统计分析基础:DataFrame的数据分析及画图功能(case:京津冀地区的gdp和人口的关系)