数据分析 # 深入分析近三年以来各大城市发展情况

项目介绍

本项目结合 matplotlib 可视化来做分析,以直观的方式展示各大城市从2015到2017年的变化情况,并加与文字说明。

目标定义

目标需求分析1:对比2015至2017年主要城市年度数据的变化趋势。
目标需求分析2:对比各个城市在这几年的国内生产总值情况,哪些城市贡献大?
目标需求分析3:对比各个城市第一、二、三产业在这几年的发展状况是怎样的?
目标需求分析4:对比各个城市平均在职工资、学校资源、卫生医院设备情况,看看哪些城市工资高、教学资源丰富、医疗保障水平是怎样的?
目标需求分析5:对比分析哪些城市是房地产投资重地呢?

实践流程

1 加载合并数据

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

df1 = pd.read_csv('/govstats2556/2015年国内主要城市年度数据.csv')
df2 = pd.read_csv('/govstats2556/2016年国内主要城市年度数据.csv')
df3 = pd.read_csv('/govstats2556/2017年国内主要城市年度数据.csv')

df = pd.concat([df1, df2, df3], axis=0)  # 以行的维度合并数据

print('\n【特征】>>>', df.columns)
# 重置索引和特征名
df.index = [i for i in range(df.shape[0])]  # 重置索引
df.columns = ['area', 'year', 'total_value', 'one_value',  'two_value', 
            'three_value','zero_value', 'inout', 'population', 'pay', 
            'student', 'hospitalt', 'realty']  # 重置列名


df.info()  # 查看数据集基本情况
df.head()
英文 中文
area 地区
year 年份
total_value 国内生产总值
one_value 第一产业增加值
twol_value 第二产业增加值
three_value 第三产业增加值
zero_value 社会商品零售总额
inout 货物进出口总额
population 年末总人口
pay 在岗职工平均工资
student 普通高等学校在校学生数
hospital 医院、卫生院数
realty 房地产开发投资额


2 数据预处理

# 探索是否有缺失值
print('\n缺失值处理前>>>', df.isnull().sum(), '\n>>>', df.shape)  

# 缺失值处理
''' 第一种方法,丢弃 '''
# df = df.dropna() 
''' 第二种方法,使用均值填充 '''
# df = df.fillna(value=df.mean())  

# 由于我们发现缺失值只在 "realty" 列,因此可以使用以下方式
df['realty'] = df['realty'].fillna(value=df['realty'].mean())

print('\n缺失值处理后>>>', df.isnull().sum(), '\n>>>', df.shape) 

3 封装可视化模板和可视化分析

def plotCity(data, plotType=None):
    
    # 设置图像风格, 网格型
    plt.style.use('ggplot')  
    
    # 解决中文乱码,坐标轴显示不出负值的问题
    plt.rcParams['font.sans-serif'] =['Microsoft YaHei']
    plt.rcParams['axes.unicode_minus'] = False
    
    # 提取各年份的数据
    dt2015 = df[df['year'] == 2015]
    dt2016 = df[df['year'] == 2016]
    dt2017 = df[df['year'] == 2017]
    
    # 可视化图像的标题
    plot_title = ['国内生产总值', '第一产业增加值', '第二产业增加值', 
                 '第三产业增加值', '社会商品零售总额', '货物进出口总额', 
                 '在岗职工平均工资', '普通高等学校在校学生数', '医院、卫生院数', 
                 '房地产开发投资额']
                 
    # ------------------------------------------------
    # 4-1、在没有指明绘制图形类型情况下,采用默认方式
    if plotType == None:
        text = print("""温馨提示:你还没有选择绘制图形的类型.....\n类型如下...
        plot\t线性图
        pie\t饼图
        bar\t纵向条形图
        barh\t横向条形图
        hist\t直方图
        boxplot\t箱型图
        scatter\t散点图
        \n例子\n---------"""
        + "\nplot(data=data, plotType='plot')")
        return text
    
    fig = plt.figure()
    for i in range(0, len(data) - 1):
    # for i in range(0, 4):
        ax = fig.add_subplot(5, 2, i + 1)
        
        # --------------------------------------------------
        # 4-2、选择绘制线形图
        if plotType == 'plot':
            ax.plot(dt2015[data[0]], dt2015[data[i + 1]], marker='o', label='2015')
            ax.plot(dt2016[data[0]], dt2016[data[i + 1]], marker='o', label='2016')
            ax.plot(dt2017[data[0]], dt2017[data[i + 1]], marker='o', label='2017')
            ax.set_title(plot_title[i])  # 标题
            ax.set_xticklabels(labels=dt2015[data[0]], rotation=90)  # 设置 X 轴刻度对应的标签
            ax.legend(loc='best')  # 图例
            fig.subplots_adjust(top=5, bottom=0.1, left=0.9, right= 3.6, 
                                hspace=0.3, wspace=0.3)  # 调整子图之间间隙
            
        # --------------------------------------------------
        # 4-3、选择绘制饼图
        if plotType == 'pie':
            ax.pie(x=dt2015[data[i + 1]], labels=dt2015[data[0]], shadow=True,
                   autopct='%.2f%%', radius=2.)
            ax.set_title(plot_title[i])  # 标题
            # ax.legend(loc='right')  # 图例
            # 调整子图间距,上下左右
            fig.subplots_adjust(top=5, bottom=0.1, left=0.9, right= 3.6, 
                                hspace=0.8, wspace=0.1)  
        
        # ---------------------------------------------------
        # 4-4、选择绘制纵向条形图
        if plotType == 'bar':
            bar_width = 0.3
            ''' 正 y 轴绘制条形图 '''
            ax.bar(x=dt2015.index, height= + dt2015[data[i + 1]],  # 正 y 半轴绘图
                   label='正轴2015',  width=bar_width)  
            ax.bar(x=dt2015.index + bar_width, height= + dt2016[data[i + 1]], # 正 y 半轴绘图
                   label='正轴2016',  width=bar_width)  
            ax.bar(x=dt2015.index + 2 * bar_width, height= + dt2017[data[i + 1]], # 正 y 半轴绘图
                   label='正轴2017', width=bar_width, color='y')  
                   
            ''' 负 y 轴绘制条形图 '''
            ax.bar(x=dt2015.index, height= - dt2015[data[i + 1]],  # 负 y 半轴绘图
                   label='负轴2015',  width=bar_width, color='r')  
            ax.bar(x=dt2015.index + bar_width, height= - dt2016[data[i + 1]],  # 负 y 半轴绘图
                   label='负轴2016',  width=bar_width, color='c')  
            ax.bar(x=dt2015.index + 2 * bar_width, height= - dt2017[data[i + 1]], # 负 y 半轴绘图
                   label='负轴2017',  width=bar_width, color='b')  
                   
            ax.set_title(plot_title[i])  # 标题
            ax.set_xticks([i for i in range(dt2015.shape[0])])  # 重置 x 轴刻度值
            ax.set_xticklabels(labels=dt2015[data[0]], rotation=90)  # 在 x 轴刻度值上设置标签,旋转 90 度 
            ax.legend(loc='best')  # 图例,自动选择最好的位置摆放图例
            # 调整子图间距,上下左右
            fig.subplots_adjust(top=5, bottom=0.1, left=0.9, right= 3.6, 
                                hspace=0.3, wspace=0.3)
        
        # ---------------------------------------------------
        # 4-5、选择绘制横向条形图
        if plotType == 'barh':
            ax.barh(y= + dt2015.index, width= dt2015[data[i + 1]], height=2, 
                    label='2015') # 正 x 半轴绘图
            ax.barh(y= - dt2015.index, width= dt2016[data[i + 1]], height=2, 
                    label='2016') # 负 x 半轴绘图
            
            ax.set_title(plot_title[i])  # 标题
            ax.set_yticks([i for i in range(dt2015.shape[0])] + 
                        [-i for i in range(dt2015.shape[0])])  # 重置 y 轴刻度值
            ax.set_yticklabels(labels=dt2015[data[0]].tolist() + 
                                dt2015[data[0]].tolist())  # 在 y 轴刻度值上设置标签
            ax.legend(loc='best')
            # 调整子图间距,上下左右
            fig.subplots_adjust(top=18, bottom=0.1, left=0.9, right= 3.6, 
                                hspace=0.3, wspace=0.3)
                                
        # ------------------------------------------------------
        # 4-6、选择绘制直方图
        color = ['r', 'g', 'c', 'b', 'm', 'r', 'g', 'c', 'b', 'm']
        if plotType == 'hist':
            ax.hist(x= -dt2015[data[i + 1]], bins=10, color=color[i], label='2015') # 正 x 半轴绘图
            ax.hist(x= dt2016[data[i + 1]], bins=10, color=color[-(i + 1)], label='2016')
            ax.legend(loc='best')  # 图例
            ax.set_title(plot_title[i])  # 标题
            # 图像文本设置
            ax.text(x=0, y=4, s='LXZ说:直方图用于探索各个元素出现的频次', fontsize=14, color='k')
            # 调整子图间距,上下左右
            fig.subplots_adjust(top=5, bottom=0.1, left=0.9, right= 3.6, 
                                hspace=0.3, wspace=0.3)
        
        # -------------------------------------------------------
        # 4-7、选择绘制箱形图
        if plotType == 'boxplot':
            # patch_artist=True 填充颜色
            ax.boxplot(x=[dt2015[data[i + 1]], dt2016[data[i + 1]], 
                        dt2017[data[i + 1]]], patch_artist=True)
            ax.set(title=plot_title[i],
                   ylabel='元素值分布',
                   xlabel='年份',
                   xticklabels=(['2015', '2016', '2017']))
            
            # 设置箭头标注,s 代表要显示的文字,xy 代表箭头的位置,xytext 代表文字
            # 的位置,arrowprops 代表设置箭头的样式
            ax.annotate(s='中位数:' + str(dt2016[data[i + 1]].median()), xy=(2, dt2016[data[i + 1]].median()),
                       xytext=(2.25, dt2016[data[i + 1]].median() + 50), fontsize=20, color='k',
                       arrowprops=dict(arrowstyle="->",connectionstyle='arc3',color='r',))
            ax.grid(True)  # 添加网格
            # 子图间隙调整           
            fig.subplots_adjust(top=5, bottom=0.1, left=0.9, right= 3.6, 
                                hspace=0.3, wspace=0.3)

测试

data = ['area', 'total_value', 'one_value',  'two_value', 
        'three_value','zero_value', 'inout', 'pay', 
        'student', 'hospitalt', 'realty']    
plotCity(data)

data = ['area', 'total_value', 'one_value',  'two_value', 
        'three_value','zero_value', 'inout', 'pay', 
        'student', 'hospitalt', 'realty']    
plotCity(data=data, plotType='plot')

第一、二、三产业百度百科介绍如下:

  • 第一产业指生产食材以及其它一些生物材料的产业,如:种植业、林业、畜牧业、水产养殖业等直接以自然物为生产对象的产业。
  • 第二产业主要指加工制造产业,利用自然界和第一产业提供的基本材料进行加工处理。
  • 第三产业是指第一、第二产业以外的其他行业,主要包括交通运输业、通讯产业、商业、餐饮业、金融业、教育产业、公共服务等非物质生产部门。

由上面的线形图可视化可分析如下:
总体来看

  • 各个省份的各项指标总体来说,呈现逐年增加的态势,不过增加的幅度不是很大

各项指标

在国内生产总值指标中

  • 北上广深、重庆占据绝对优势
  • 太原、呼和浩特、海口、西宁倒数,占比最小

在第一、二、三产业指标中

  • 重庆是第一、第二产业龙头
  • 北上广深是第二、三产业龙头

在零售总额指标中

  • 北上广深、重庆不负众望,仍然占据绝对优势

在货物进出口指标中

  • 北上深以绝对的优势碾压各省
  • 其他省份普遍较低

在平均工资指标中

  • 北上广深,拉萨占比较大

在校学生数指标中

  • 宁夏、厦门、深圳、海口、拉萨、西宁、银川占比最小
  • 深圳虽然是一线城市,但是大学学校不多

在医院数指标中

  • 重庆、成都占比较大

在房地产投资指标中

  • 北京、上海、杭州、郑州、广州、重庆、西安占比较大

综上所述

  • 发展比较好的城市:北上广深、重庆
  • 发展比较落后的城市:太原、呼和浩特、海口、西宁

data = ['area', 'total_value', 'one_value',  'two_value', 
        'three_value','zero_value', 'inout', 'pay', 
        'student', 'hospitalt', 'realty']    
plotCity(data=data, plotType='pie')

data = ['area', 'total_value', 'one_value',  'two_value', 
        'three_value','zero_value', 'inout', 'pay', 
        'student', 'hospitalt', 'realty']    
plotCity(data=data, plotType='bar')

data = ['area', 'total_value', 'one_value',  'two_value', 
        'three_value','zero_value', 'inout', 'pay', 
        'student', 'hospitalt', 'realty']    
plotCity(data=data, plotType='barh')

data = ['area', 'total_value', 'one_value',  'two_value', 
        'three_value','zero_value', 'inout', 'pay', 
        'student', 'hospitalt', 'realty']    
plotCity(data=data, plotType='hist')

data = ['area', 'total_value', 'one_value',  'two_value', 
        'three_value','zero_value', 'inout', 'pay', 
        'student', 'hospitalt', 'realty']    
plotCity(data=data, plotType='boxplot')

雷达图可视化探索

下面将以雷达图来探索 36 个省 2015、2016、2017年的变化情况
探索指定的特征三年来的变化
第二产业增加值
年末总人口
房地产开发投资额
批量绘制 36 个雷达图…

# 将'year'设置成索引列
df = df.set_index(keys='year') 

import numpy as np


def leida(city):
    
    # 正常显示中文、坐标轴负号的问题
    plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
    plt.rcParams['axes.unicode_minus'] = False

    fig = plt.figure()  # 设置画布
    plt.style.use('ggplot')  # 图像风格
    
    # 特征的标签
    labels = ['第二产业增加值', '年末总人口', '房地产开发投资额']
    
    for i in range(len(city)):
        
        # 各省数据
        # beijing = df[df['area'] == '北京']
        values1 = df[df['area'] == city[i]].iloc[0, [3, 7, 11]].tolist()  # 2015 年
        values2 = df[df['area'] == city[i]].iloc[1, [3, 7, 11]].tolist()  # 2016 年
        values3 = df[df['area'] == city[i]].iloc[2, [3, 7, 11]].tolist()  # 2017 年
        # print(values1, values2)
        
        # 分配角度
        angles = np.linspace(0, 2 * np.pi, len(values1), endpoint=False)
        
        # 将数据和角度连接成一个圆圈
        values1 = np.concatenate((values1, [values1[0]]))
        values2 = np.concatenate((values2, [values2[0]]))
        values3 = np.concatenate((values3, [values3[0]]))
        angles = np.concatenate((angles, [angles[0]]))

        # 36 个省,绘制 18 x 2 个子图
        ax = fig.add_subplot(18, 2, i + 1, polar=True)  # polar=True 代表绘制极坐标图
        
        ''' 
        绘制雷达图:
        marker='o' 代表设置点的样式为"圆圈"
        linewidth 线条的宽度
        label 标签,与图例共同使用
        '''
        ax.plot(angles, values1, marker='v', color= 'r', linewidth=1.5, label='2015')
        ax.fill(angles, values1, alpha=0.25)
        
        ax.plot(angles, values2, marker='v', color= 'm', linewidth=1.5, label='2016')
        ax.fill(angles, values2, alpha=0.25)
        
        ax.plot(angles, values3, marker='o', color= 'c', linewidth=1.5, label='2017')
        ax.fill(angles, values3, alpha=0.25)
        ax.set_thetagrids(angles * 180 / np.pi, labels)  # 标注上特征标签
        
        ax.set_title(city[i])  # 设置标题
        plt.legend(loc='center left')  # 图例, 左边中部
        ax.grid(True)  # 添加网格
        # 子图间隙调整,top 主要控制子图高度,right 主要控制子图宽度,
        # left 调整子图之间左右的间隙,bottom 调整上下间隙
        # fig.subplots_adjust(top=30, right=15, left=9)  # 左右间隙过大
        # fig.subplots_adjust(top=30, right=15, left=14)  # 上下间隙过大
        fig.subplots_adjust(top=30, right=15, left=14, bottom=17)
        
# ----------------------------------------
# 测试调用雷达图
# tolist() 代表转换成列表
city = df['area'][:36].tolist()
leida(city)

发布了634 篇原创文章 · 获赞 579 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/qq_33583069/article/details/103041489