Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析

✅作者简介:大家好我是Xlong,一枚正在学习COMSOL、Python的工科研究僧
📃个人主页:Xlong的个人博客主页
🔥系列专栏:Python大数据分析
💖如果觉得博主的文章还不错,请👍支持博主🤞

内容

1.绘画之美

2.基于数据透视表的数据分析

1.绘画之美

做数据分析,图、表、文字是展示分析结果时使用的三种手段。其中,图最为直观,也是读者/观众最容易接收的信息。因此,图的合理、准确、美观是数据分析工作中最重要的部分之一。

例如,在学术论文中,学术期刊的水平越高,发表的论文中的图片就越漂亮。

该网站内有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())

运行结果:

第三产业增加值地区GDP
北京市     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()

运行结果:

Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析

数据分析第二步:尝试建立一些指标,画图看是否合适

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()

Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析

由于量级不同,需要分别绘制

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()

Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析

由于第三产业增加值、地区生产总值、第三产业对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()

Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析

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()命令也可以

Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析

此外,python还有很多作图包可以很简单的画出漂亮的图。如seaborn。seaborn: statistical data visualization — seaborn 0.11.2 documentation

2.基于数据透视表的数据分析

运用透视表功能进行分析 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()

运行结果:


(2,)

Pandas统计分析基础(7):画图美观性及基于数据透视表的数据分析

两者在数据的统计、聚合功能上没有显著区别.但在显示模式(包括直观显示和默认画图)上的差别,数据透视表在显示上更友好一些。

这也是由他们生成的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,感谢!!!

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年3月27日 下午2:25
下一篇 2022年3月27日 下午2:44

相关推荐