Python大数据分析8:案例-各省的人都往哪儿去?

这次我们结合人口流动的数据来看看我国人口在各省之间的移动特点,并据此从人口流动的角度,来分析下我国各省的相关性。当然,这里主要利用的还是各种pyecharts可视化分析方法。

首先我们加载人口迁移数据:

# coding:utf-8

import pandas as pd

frame = pd.read_csv(‘C:\\temp\\population.csv’, encoding=’GBK’)

print(frame)

该数据有三列,分别是流出省份、流入省份和人口流动数量,共计840条数据。这些数据都是从1985年到1990年共计5年的人口汇总统计数据。

为了更好的了解数据,我们首先对数据按照人口流动数量降序排列输出来观察下:

pd.set_option(‘display.max_rows’, None)

print(frame.sort_values(by=[‘count’], ascending=False))

我们发现,数据呈现快速下降的特点,我们可以选择大于10万的记录即可展示最为主要的流动关系。

有时候,可能会有这样的输出,这种情况并非错误,如果pandas在解析数据时,将最后count理解为字符,那么确实就是这个次序。对于字符而言,首先比较左边第一个字符,谁大就谁大,后面就不再比较,只有左边第一个字符一样,才会比较第二个,仍然按照刚才规则进行。

此时可以考虑强制转换为整数列:

frame[‘count’] = pd.to_numeric(frame[‘count’])

print(frame.sort_values(by=[‘count’], ascending=False))

这里的pandas自带的to_numeric也可以完成字符向数字的转换。

我们首先还是以地图可视化来展示下效果。这里需要展示的是一种省份之间的流向关系,因此需要使用线条来表示:

# coding:utf-8
import pandas as pd
from pyecharts.charts import Geo
from pyecharts import options as opts
from pyecharts.globals import ChartType

frame = pd.read_csv('C:\\temp\\population.csv', encoding='GBK')
results = frame[frame['count'] > 100000][['from', 'to']].values.tolist()
geo = Geo()
geo.add_schema(maptype="china")
geo.add("", results, type_=ChartType.LINES, linestyle_opts=opts.LineStyleOpts(curve=0.2))
geo.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
geo.render()

这里注意几个问题:

一是我们得到了人口流动数量大于10万的记录,并将这些数据设置为显示数据;

二是在图样显示中,我们将类型设置为线条,并通过curve属性将其设置为曲线。

从图中可以看出,这里实际显示的箭头是动态的,四川和黑龙江是人口流出大省,其中北京、上海、广东都是一些人口流入的重要地区。

我们再以另外一个角度来展示分析效果。比如就看流入情况:

# coding:utf-8
import pandas as pd

frame = pd.read_csv('C:\\temp\\population.csv', encoding='GBK')
results = frame[['count']].groupby(frame['to']).sum()
results = results.reset_index()
results = results.values.tolist()
print(results)

以人口流入数量按照省份汇总,形成每个省份的总数据。这里要注意一个问题,由于汇总后省份列变成了索引,因此通过reset_index按索引恢复过来,形成可以直接转换为list的数据格式。

这次我们以热点图的类型展示了结果:

# coding:utf-8
import pandas as pd
from pyecharts.charts import Geo
from pyecharts import options as opts
from pyecharts.globals import ChartType

frame = pd.read_csv('C:\\temp\\population.csv', encoding='GBK')
results = frame[['count']].groupby(frame['to']).sum()
results = results.reset_index()
results = results.values.tolist()
geo = Geo()
geo.add_schema(maptype="china")
geo.add("", results, type_=ChartType.HEATMAP)
geo.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
geo.set_global_opts(visualmap_opts=opts.VisualMapOpts(max_=1300000))
geo.render()

再次看出我们人口流入大省的分布情况,仍然主要集中在华南、华东和华北三块,依次递减。

接下来我们准备换个思路来看这个问题,通过人口在不同省份之间的流入流出,其实也能在一定程度上反映省份的关系,我们这次结合网络图来重新分析下省份之间的关系。

网络图其实需要两个基本数据,一个是节点,一个节点之间的边。为此我们来整理下数据。

首先我们得到边,然后根据边确定节点。考虑到界面显示有限,显示太多边会导致无法看清内容,因此我们做了必要的筛选,

# coding:utf-8

import pandas as pd

frame = pd.read_csv(‘C:\\temp\\population.csv’, encoding=’GBK’)

frame = frame[frame[‘count’] > 50000]

links = frame[[‘from’, ‘to’]].rename(columns={‘from’: ‘source’, ‘to’: ‘target’}).to_dict(orient=’records’)

print(links)

这里我们先过滤到现有人口流动数量不高于5万的省份流动记录。对于pyecharts,它也提供了专门的Graph类型用于绘制网络图。但是它要求对边做出固定格式的定义,从结果来看,是一种字典格式。因此,我们通过调用rename改名将列名换为source和target,这里的名称就表示源和目标,然后利用to_dict生成特定的字典格式。可以从结果看出,里面的信息很明确。

我们再得到节点:

results = frame[[‘count’]].groupby(frame[‘to’]).sum()

results[‘name’] = results.index

results[‘count’] = results[‘count’] / 50000

results = results.rename(columns={‘count’: ‘symbolSize’})

nodes = results.to_dict(orient=’records’)

print(nodes)

这里首先根据流入人口汇总,为方便索引的身份信息也转换为后续的字典内容,因此和以前一样,新增列保存为索引一样的内容,同时,新列名称必须为name,表示节点名称,而汇总的人数作为权值,可以利用节点大小来反映,为此需要将列名改为symbolSize,同时由于数值太大,因此可以考虑适当缩小,这里采取了除以最小数值的方法。

有了上述基础数据,我们就以完成绘制:

# coding:utf-8
import pandas as pd
from pyecharts.charts import Graph

frame = pd.read_csv('C:\\temp\\population.csv', encoding='GBK')
frame = frame[frame['count'] > 50000]
links = frame[['from', 'to']].rename(columns={'from': 'source', 'to': 'target'}).to_dict(orient='records')
results = frame[['count']].groupby(frame['to']).sum()
results['name'] = results.index
results['count'] = results['count'] / 50000
results = results.rename(columns={'count': 'symbolSize'})
nodes = results.to_dict(orient='records')
graph = Graph()
graph.add("", nodes, links)
graph.render()

首先要导入Graph类型,生成Graph类型变量,然后add函数中指定节点和边,第一个参数是标题。

从中可以明显看出,从人口流动关系来看,我国不同省份之间的联系。有几个明显的特征:比如以辽宁为中心的北方各省形成一个相对闭合的关系,四川为人口流动的大省,并通过河北和北方其他几个省市建立了联系,并通过江苏和华东几省也建立了联系。

为了增强效果,可以进一步增加显示范围,同时增加边的样式:

graph = Graph(init_opts=opts.InitOpts(width=”1600px”, height=”800px”))

graph.add(“”, nodes, links, linestyle_opts=opts.LineStyleOpts(width=0.5, curve=0.3, opacity=0.7))

graph.render()

这些都可以自由调整。

也可以改变显示模式,改为圆盘显示:

graph.add(“”, nodes, links, layout=”circular”)

graph.render()

结果展示方式变成了新的模样。不同的效果可以根据显示数据的分析要求来选择。

发表评论

电子邮件地址不会被公开。 必填项已用*标注