• 图解2022年城市人口迁移趋势


    前言

    现在已经是疫情发生后的第3个年头了,截止当前疫情已经成为一个常态化的趋势,在疫情的影响下,各个行业都在发生变化,不管是之前的教培类落幕还是当前互联网裁员大潮,都是和经济环境变化有关。不管什么时候人口都是城市发展的一个重大要素,今天我们就来看下2022年,城市人口有了哪些新的变化。今天我们就是用Python爬取人口迁移的数据,一看究竟。

    一、数据提取

    巧妇难为无米之炊,数据分析的主材就是数据。于是,我准备用Python爬取百度迁移。数据来源百度人口迁移大数据
    在这里插入图片描述
    爬取数据前我们先来认识下百度迁徙大数据的指标,最右侧的数据是从上海6月21日的迁出人口到各个城市的占比,例如6月21日迁出1万人,分别到苏州2.7万,占比27%,到嘉兴市8790人,占比8.79%等。
    下面的折现图,表示的迁出指数,迁出指数是百度脱敏后的数据,但是横向是可以对比的,例如6月21日上海流出指数市2.33,同日重庆迁出指数是3.614,那么同日重庆迁出人口多于上海。

    1、抓包解析数据

    使用谷歌浏览器输入 http://qianxi.baidu.com/#/,抓包的正常流程,按F12在右边栏中找出如下的网址就是我们需要的每天的人口迁入数据了
    在这里插入图片描述
    同理我们可以找到我们需要抓的数据包:

    #上海每天迁入数据
    1、历史迁徙指数网址解析——迁出
    http://huiyan.baidu.com/migration/historycurve.jsonp?dt=province&id=310000&type=move_out&callback=jsonp_1655998090386_5878574
    上面的id=310000中id就是城市的代码了,type=move_out就是迁出了,由于这个是callback=jsonp_1655998090386_5878574这一堆是时间戳的一个换算,这里删除不耽误我们取数据所以就不管这些了
    所以这个就可以直接使用爬取网站http://huiyan.baidu.com/migration/historycurve.jsonp?dt=province&id=310000&type=move_out
    
    2、每天迁徙指数网址解析——迁出城市排行
    http://huiyan.baidu.com/migration/cityrank.jsonp?dt=province&id=310000&type=move_out&date=20220621&callback=jsonp_1655998090383_2252003
    上面的id=310000中id就是城市的代码了,type=move_out就是迁出了,date=20220621表示日期,由于这个是callback=jsonp_1655911605037_4686874这一堆是时间戳的一个换算,这里删除不耽误我们取数据所以就不管这些了
    所以可以使用“http://huiyan.baidu.com/migration/cityrank.jsonp?dt=province&id=310000&type=move_out&date=”+日期,就可以爬取每天的数据了
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、爬取数据

    提取数据,提取从2022年1月至2022年6月20日的数据,逻辑如下:

    # -*- coding: utf-8 -*-
    import requests #导入请求模块
    import json #导入json模块
    import re
    import pandas as pd
    import numpy as np
    import datetime
    import time #导入时间模块
    
    
    def get_history_migrate_data(url,param):
        '''
        使用requests包抓取网页数据,使用get请求
        :param url: 网址
        :param param: 网址所带的参数
        :return: 返回迁徙数据
        '''
        html = requests.get(url,params=param)
        city = json.loads(re.findall(r'[(](.*?)[)]', html.text)[0])
        try:
            data_list = city['data']['list']
        except Exception as e:
            print(f'获取网址{html.url}数据失败!',f'返回内容{city}',e)
        #由于历史迁徙数据中list只有一个
        if type(data_list)==list :
            data = pd.DataFrame(data_list)
        else:
            data =pd.DataFrame({'date':data_list.keys(),'value':data_list.values()})
        return data
    
    def get_out_city(url,param,dt_date_begin='20220101',dt_date_end='20220620'):
        '''
        通过变化日期,获取每天迁出城市排名数据
        :param url: 网址
        :param param: 网址参数
        :param dt_date_begin: 开始提取日期
        :param dt_date_end: 截止提取日期
        :return: 返回每天迁出城市排名数据
        '''
        param['date']=dt_date_begin
        list_data =get_history_migrate_data(url,param)
        list_data['date'] = dt_date_begin
        while dt_date_begin < dt_date_end:
        	#监控打印
            if dt_date_begin in ('20220201','20220301','20220401','20220501','20220501'):
                print(dt_date_begin)
            dt_date_begin = (datetime.datetime.strptime(dt_date_begin,'%Y%m%d') + datetime.timedelta(days=1)).strftime('%Y%m%d')
            param['date']=dt_date_begin
            data = get_history_migrate_data(url,param)
            data['date'] = dt_date_begin
            list_data = pd.concat([list_data,data])
        return list_data
    
    #提取历史数据
    if __name__ == "__main__":
        #历史迁徙数据url
        cities_code = pd.read_excel(r'E:\桌面\城市编号列表.xlsx')
        url_history = r'http://huiyan.baidu.com/migration/historycurve.jsonp?dt=province'  #历史迁徙指数
        url = r'http://huiyan.baidu.com/migration/cityrank.jsonp?dt=province'              #每天迁出人口所到城市排名
        param = {
        'id':'310000',   #上海市的代码
        'type':'move_out', #迁出类型
        }                                                         #get请求参数,城市排名需要加入日期,即格式如下 'date':'20220601'
        data_history = []
        #爬取285个城市历史迁出迁入指数
        for code_city,city_name in zip(cities_code['城市编号'],cities_code['城市']):
            param['id']=code_city
            param['type']='move_out'
            history_out_city =get_history_migrate_data(url_history,param)
            history_out_city.rename(columns={'value':'迁出指数'},inplace=True)
            history_out_city['城市']=city_name
            param['type'] = 'move_in'
            history_in_city = get_history_migrate_data(url_history,param)
            history_in_city.rename(columns={'value': '迁入指数'}, inplace=True)
            data_history.append(pd.merge(history_out_city,history_in_city,how='left',on='date'))
        data_history_data = pd.concat(data_history,axis=0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    二、数据处理

    1、数据指标理解
    由于当前的数据是脱敏的数据,其中迁出城市数据是排名数据,迁徙数据是脱敏后的指数,指数可以横向及纵向对比。
    由全国的迁徙指数来看,迁出等于迁入,这里假设全国来看迁出=迁入,整体规模指数是相同的,这里认为迁徙指数是同量纲的,即迁出指数和迁入指数是一个量纲的。
    2、指标处理逻辑
    我们假设在每天的迁徙指出指数是 N j i N_j^i Nji,其中表示第 i i i j j j(j=0表示迁出,j=1表示迁入), P m j i P_{mj}^i Pmji 表示第 i i i m m m城迁入迁出( j = 0 j=0 j=0表示迁出, j = 1 j=1 j=1迁入)指数,那么 ∑ i = 1 n ∑ j = 0 1 N j i ∗ ( − 1 ) j \sum_{i=1}^n\sum_{j=0}^1N_j^i*(-1)^j i=1nj=01Nji(1)j表示n天内净的迁出量, ∑ i = 1 n ∑ j = 0 1 N j i ∗ P m j i ∗ ( − 1 ) j \sum_{i=1}^n\sum_{j=0}^1N_j^i*P_{mj}^i*(-1)^j i=1nj=01NjiPmji(1)j表示m城在n天内净迁出的指数,然后按照净迁出多少排名,可以计算出从上海净迁出最多的几个城市。
    1)找出top10迁出迁出的城市

    data_history_data['净迁出指数'] = data_history_data['迁出指数']-data_history_data['迁入指数']
    #选取近一年的数据,即2021年6月1日-2022年5月31日一个整年度
    data_history_data_copy = data_history_data[(pd.to_datetime(data_history_data['date'])>= pd.to_datetime('20220520')) & ( pd.to_datetime(data_history_data['date'])< pd.to_datetime('20220620')) ].copy()
    top_year=data_history_data_copy.groupby('城市').agg({'净迁出指数':'sum'})
    #找出净迁出top10,
    top_year['净迁出指数'].nlargest(10)
    #净迁入top10的城市
    top_year['净迁出指数'].nsmallest(10)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2)计算深圳和上海的5月20日-6月19日的迁出城市总排名

        city_rank_list =[]
        for code_city,city_name in zip(['440300','310000'],['深圳市','上海市']): #深圳、上海
            for dt in range(31):
                dt_date = (datetime.datetime.strptime('20220520','%Y%m%d') + datetime.timedelta(days=dt)).strftime('%Y%m%d')
                param['id']=code_city
                param['type']='move_out'
                param['date']=dt_date
    
                data_history_data = get_history_migrate_data(url,param)
                data_history_data['出发城市']=city_name
                data_history_data['日期']=dt_date
                city_rank_list.append(data_history_data)
        city_rank_list = pd.concat(city_rank_list)
        #计算总体排名,使用城市迁出排名*当天的迁出指数 可以计算当前迁出到某个城市的指数,在综合计算近一个月内的总迁出指数
        city_rank_list_zhishu = pd.merge(city_rank_list,data_history_data_copy[['城市','date','迁出指数']],how='left',left_on=['日期','出发城市'],right_on=['date','城市'])
        city_rank_list_zhishu['城市迁出指数'] = city_rank_list_zhishu['value']*city_rank_list_zhishu['迁出指数']/100
        result=city_rank_list_zhishu.groupby(['出发城市','city_name']).agg({'城市迁出指数':'sum'})
        #查看深圳市近一个月迁出城市排名
        result.xs('深圳市', axis=0, level=0)['城市迁出指数'].nlargest(10).index.to_list()
        result.xs('上海市',axis=0,level=0)['城市迁出指数'].nlargest(10).index.to_list()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    三、数据分析及展示

    1、查看近5月20日至6月20日,人口净迁出指指数top的城市

    城市净迁出指数排名
    深圳市28.2030661
    上海市26.6993172
    成都市23.0957893
    郑州市20.9520434
    北京市12.0067275
    东莞市11.7499256
    广州市8.5247327
    佛山市7.6919878
    宁波市7.4844009
    天津市6.61799210

    查看近1个月人口净流入top的城市

    城市净迁入指数排名
    惠州市15.1561371
    清远市8.6193072
    眉山市5.5048573
    忻州市5.3032004
    江门市5.1670225
    南京市5.1485226
    南宁市5.0367427
    肇庆市4.9094758
    商丘市4.2683449
    济南市4.21232410

    2、下面我们查看下近一个月内净迁出指数top10城市主要迁出城市分布
    深圳迁出前十的城市分别是’东莞市’, ‘惠州市’, ‘广州市’, ‘佛山市’, ‘汕尾市’, ‘河源市’, ‘中山市’, ‘揭阳市’, ‘梅州市’, ‘珠海市’。

    city_rank_list_zhishu = pd.merge(city_rank_list,data_history_data_copy[['城市','date','迁出指数']],how='left',left_on=['日期','出发城市'],right_on=['date','城市'])
    city_rank_list_zhishu['城市迁出指数'] = city_rank_list_zhishu['value']*city_rank_list_zhishu['迁出指数']/100
    result=city_rank_list_zhishu.groupby(['出发城市','city_name']).agg({'城市迁出指数':'sum'})
    #查看深圳市近一个月迁出城市排名
    shenzhen=result.xs('深圳市', axis=0, level=0)['城市迁出指数'].nlargest(10)
    shanghai=result.xs('上海市',axis=0,level=0)['城市迁出指数'].nlargest(10).index.to_list()
    data_1=list([(x[:-1],y) for x,y in zip(shenzhen.index.to_list(),shenzhen.to_list())])
    date_2=list([('深圳',x) for x in shenzhen.index.to_list()])
    #使用pyecharts来看展示图
    from pyecharts import options as opts
    from pyecharts.charts import Geo
    from pyecharts.globals import ChartType, SymbolType
    c = (
        Geo()
        .add_schema(
            maptype="china",
            itemstyle_opts=opts.ItemStyleOpts( color="#323c48",border_color="#111"),
        )
        .add(
            "",
            data_1,
            type_=ChartType.EFFECT_SCATTER,
            color="white",
        )
        .add(
            "geo",
            data_2,
            type_=ChartType.LINES,
            effect_opts=opts.EffectOpts(
                symbol=SymbolType.ARROW, symbol_size=6, color="blue"
            ),
            linestyle_opts=opts.LineStyleOpts(curve=0.2),
        )
        .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        .set_global_opts(title_opts=opts.TitleOpts(title="深圳人口迁出前十城市"))
      
    )
    c.render_notebook()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    由于深圳迁出的城市分布在广东省,这里截取了一部分的图例
    在这里插入图片描述

    四、结论

    近一个月内,净流出人口的城市主要是较大,且发生疫情的城市。说明疫情对人们的生活影响相对较大。由于百度指数处理相对麻烦,且含义相对不好理解,这里只做简单分析。有兴趣,大家可以自行分析。

  • 相关阅读:
    Node.js安装教程【附安装包资源】
    vs c++ 代码 c2362错误
    线性代数本质系列(二)矩阵乘法与复合线性变换,行列式,三维空间线性变换
    ROS 开源项目 TurtleBot3 安装与使用
    什么是原生IP与广播IP?如何区分判定?
    QTday5
    HTML中如何给代码添加注释
    【云原生 · Kubernetes】kubernetes v1.23.3 二进制部署(一)
    【SpringBoot笔记31】SpringBoot之配置过滤器Filter的方式、配置拦截器Interceptor的方式
    VS Code连接远程Linux服务器开发c++项目
  • 原文地址:https://blog.csdn.net/suhao0911/article/details/125418382