内容简介:这是涛哥给你推荐的第24篇好文
这是涛哥给你推荐的第24篇好文
来源:法纳斯特 | 作者:小F
最近看了新周刊的一篇推送,有关地铁名字的分析,链接如下。
于是乎也想着自己去获取数据,然后进行分析一番。
当然分析水平不可能和他们的相比,毕竟文笔摆在那里,也就那点水平。
大家看着乐呵就好, 能提高的估摸着也就只有数据的准确性啦。
文中所用到的地铁站数据并没有去重,对于换乘站,含有大量重复。
即使作者一直在强调换乘站占比很小,影响不是很大。
但于我而言,去除重复数据还是比较简单的。
然后照着人家的路子去分析,多学习一下。
/ 01 / 获取分析
地铁信息获取从高德地图上获取。
上面主要获取城市的「 id 」, 「 cityname 」 及 「 名称 」 。
用于拼接请求网址,进而获取地铁线路的具体信息。
找到请求信息,获取各个城市的地铁线路以及线路中站点详情。
/ 02 / 数据获取
具体代码如下。
import json import requests from bs4 import BeautifulSoup headers = {'user-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'} def get_message(ID, cityname, name): """ 地铁线路信息获取 """ url = 'http://map.amap.com/service/subway?_1555502190153&srhdata=' + ID + '_drw_' + cityname + '.json' response = requests.get(url=url, headers=headers) html = response.text result = json.loads(html) for i in result['l']: for j in i['st']: # 判断是否含有地铁分线 if len(i['la']) > 0: print(name, i['ln'] + '(' + i['la'] + ')', j['n']) with open('subway.csv', 'a+', encoding='gbk') as f: f.write(name + ',' + i['ln'] + '(' + i['la'] + ')' + ',' + j['n'] + '\n') else: print(name, i['ln'], j['n']) with open('subway.csv', 'a+', encoding='gbk') as f: f.write(name + ',' + i['ln'] + ',' + j['n'] + '\n') def get_city(): """ 城市信息获取 """ url = 'http://map.amap.com/subway/index.html?&1100' response = requests.get(url=url, headers=headers) html = response.text # 编码 html = html.encode('ISO-8859-1') html = html.decode('utf-8') soup = BeautifulSoup(html, 'lxml') # 城市列表 res1 = soup.find_all(class_="city-list fl")[0] res2 = soup.find_all(class_="more-city-list")[0] for i in res1.find_all('a'): # 城市ID值 ID = i['id'] # 城市拼音名 cityname = i['cityname'] # 城市名 name = i.get_text() get_message(ID, cityname, name) for i in res2.find_all('a'): # 城市ID值 ID = i['id'] # 城市拼音名 cityname = i['cityname'] # 城市名 name = i.get_text() get_message(ID, cityname, name) if __name__ == '__main__': get_city()
最后成功获取数据。
包含换乘站数据,一共3541个地铁站点。
/ 03 / 数据可视化
先对数据进行清洗,去除重复的换乘站信息。
from wordcloud import WordCloud, ImageColorGenerator from pyecharts import Line, Bar import matplotlib.pyplot as plt import pandas as pd import numpy as np import jieba # 设置列名与数据对齐 pd.set_option('display.unicode.ambiguous_as_wide', True) pd.set_option('display.unicode.east_asian_width', True) # 显示10行 pd.set_option('display.max_rows', 10) # 读取数据 df = pd.read_csv('subway.csv', header=None, names=['city', 'line', 'station'], encoding='gbk') # 各个城市地铁线路情况 df_line = df.groupby(['city', 'line']).count().reset_index() print(df_line)
通过城市及地铁线路进行分组,得到全国地铁线路总数。
一共183条地铁线路。
def create_map(df): # 绘制地图 value = [i for i in df['line']] attr = [i for i in df['city']] geo = Geo("已开通地铁城市分布情况", title_pos='center', title_top='0', width=800, height=400, title_color="#fff", background_color="#404a59", ) geo.add("", attr, value, is_visualmap=True, visual_range=[0, 25], visual_text_color="#fff", symbol_size=15) geo.render("已开通地铁城市分布情况.html") def create_line(df): """ 生成城市地铁线路数量分布情况 """ title_len = df['line'] bins = [0, 5, 10, 15, 20, 25] level = ['0-5', '5-10', '10-15', '15-20', '20以上'] len_stage = pd.cut(title_len, bins=bins, labels=level).value_counts().sort_index() # 生成柱状图 attr = len_stage.index v1 = len_stage.values bar = Bar("各城市地铁线路数量分布", title_pos='center', title_top='18', width=800, height=400) bar.add("", attr, v1, is_stack=True, is_label_show=True) bar.render("各城市地铁线路数量分布.html") # 各个城市地铁线路数 df_city = df_line.groupby(['city']).count().reset_index().sort_values(by='line', ascending=False) print(df_city) create_map(df_city) create_line(df_city)
已经开通地铁的城市数据,还有各个城市的地铁线路数。
一共32个城市开通地铁,其中北京、上海线路已经超过了20条。
城市分布情况。
大部分都是省会城市,还有个别经济实力强的城市。
线路数量分布情况。
可以看到大部分还是在「0-5」这个阶段的,当然最少为1条线。
# 哪个城市哪条线路地铁站最多 print(df_line.sort_values(by='station', ascending=False))
探索一下哪个城市哪条线路地铁站最多。
北京10号线第一,重庆3号线第二。
还是蛮怀念北京1张票,2块钱地铁随便做的时候。
可惜好日子一去不复返了。
去除重复换乘站数据。
# 去除重复换乘站的地铁数据 df_station = df.groupby(['city', 'station']).count().reset_index() print(df_station)
一共包含3034个地铁站,相较新周刊中3447个地铁站数据。
减少了近400个地铁站。
接下来看一下哪个城市地铁站最多。
# 统计每个城市包含地铁站数(已去除重复换乘站) print(df_station.groupby(['city']).count().reset_index().sort_values(by='station', ascending=False))
32个城市,上海第一,北京第二。
没想到的是,武汉居然有那么多地铁站。
现在来实现一下新周刊中的操作,生成地铁名词云。
def create_wordcloud(df): """ 生成地铁名词云 """ # 分词 text = '' for line in df['station']: text += ' '.join(jieba.cut(line, cut_all=False)) text += ' ' backgroud_Image = plt.imread('rocket.jpg') wc = WordCloud( background_color='white', mask=backgroud_Image, font_path='C:\Windows\Fonts\华康俪金黑W8.TTF', max_words=1000, max_font_size=150, min_font_size=15, prefer_horizontal=1, random_state=50, ) wc.generate_from_text(text) img_colors = ImageColorGenerator(backgroud_Image) wc.recolor(color_func=img_colors) # 看看词频高的有哪些 process_word = WordCloud.process_text(wc, text) sort = sorted(process_word.items(), key=lambda e: e[1], reverse=True) print(sort[:50]) plt.imshow(wc) plt.axis('off') wc.to_file("地铁名词云.jpg") print('生成词云成功!') create_wordcloud(df_station)
词云图如下。
广场、大道、公园占了前三,和新周刊的图片一样,说明分析有效。
words = [] for line in df['station']: for i in line: # 将字符串输出一个个中文 words.append(i) def all_np(arr): """ 统计单字频率 """ arr = np.array(arr) key = np.unique(arr) result = {} for k in key: mask = (arr == k) arr_new = arr[mask] v = arr_new.size result[k] = v return result def create_word(word_message): """ 生成柱状图 """ attr = [j[0] for j in word_message] v1 = [j[1] for j in word_message] bar = Bar("中国地铁站最爱用的字", title_pos='center', title_top='18', width=800, height=400) bar.add("", attr, v1, is_stack=True, is_label_show=True) bar.render("中国地铁站最爱用的字.html") word = all_np(words) word_message = sorted(word.items(), key=lambda x: x[1], reverse=True)[:10] create_word(word_message)
统计一下,大家最喜欢用什么字来命名地铁。
路最多,在此之中上海的占比很大。
不信往下看。
# 选取上海的地铁站 df1 = df_station[df_station['city'] == '上海'] print(df1)
统计上海所有的地铁站,一共345个。
选取包含路的地铁站。
# 选取上海地铁站名字包含路的数据 df2 = df1[df1['station'].str.contains('路')] print(df2)
有210个,约占上海地铁的三分之二,路的七分之二。
看来上海对 路 是情有独钟的。
具体缘由这里就不解释了,详情见新周刊的推送,里面还是讲解蛮详细的。
武汉和重庆则是对 家 这个词特别喜欢。
标志着那片土地开拓者们的籍贯与姓氏。
# 选取武汉的地铁站 df1 = df_station[df_station['city'] == '武汉'] print(df1) # 选取武汉地铁站名字包含家的数据 df2 = df1[df1['station'].str.contains('家')] print(df2) # 选取重庆的地铁站 df1 = df_station[df_station['city'] == '重庆'] print(df1) # 选取重庆地铁站名字包含家的数据 df2 = df1[df1['station'].str.contains('家')] print(df2)
武汉共有17个,重庆共有20个。
看完家之后,再来看一下名字包含 门 的地铁站。
def create_door(door): """ 生成柱状图 """ attr = [j for j in door['city'][:3]] v1 = [j for j in door['line'][:3]] bar = Bar("地铁站最爱用“门”命名的城市", title_pos='center', title_top='18', width=800, height=400) bar.add("", attr, v1, is_stack=True, is_label_show=True, yaxis_max=40) bar.render("地铁站最爱用门命名的城市.html") # 选取地铁站名字包含门的数据 df1 = df_station[df_station['station'].str.contains('门')] # 对数据进行分组计数 df2 = df1.groupby(['city']).count().reset_index().sort_values(by='line', ascending=False) print(df2) create_door(df2)
一共有21个城市,地铁站名包含门。
其中北京,南京,西安作为多朝古都,占去了大部分。
具体的地铁站名数据。
# 选取北京的地铁站 df1 = df_station[df_station['city'] == '北京'] # 选取北京地铁站名字包含门的数据 df2 = df1[df1['station'].str.contains('门')] print(df2) # 选取南京的地铁站 df1 = df_station[df_station['city'] == '南京'] # 选取南京地铁站名字包含门的数据 df2 = df1[df1['station'].str.contains('门')] print(df2) # 选取西安的地铁站 df1 = df_station[df_station['city'] == '西安'] # 选取西安地铁站名字包含门的数据 df2 = df1[df1['station'].str.contains('门')] print(df2)
输出如下。
/ 03 / 总结
源码及相关文件已上传GitHub,点击阅读原文即可获取。
这里摘一段新周刊的话。
可以说,一个小小的地铁名就是一座城市风貌的一部分。
它反映着不同地方的水土,也承载着各个城市的文化和历史。
确实如此,靠山的城市地铁名多“山”,靠水的城市地铁名“含水量”则是杠杠的。
万水千山总是情,点个「 在看 」行不行。
推荐阅读
··· END ···
支持小F原创 ☟
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 基于 HTML5 WebGL 的地铁站 3D 可视化系统
- 基于 HTML5 WebGL 的地铁站 3D 可视化系统
- 微信乘车码接入郑州地铁
- Downer与新南威尔士州政府合作 维护悉尼地铁运行
- WWDC 2019 的这支开场影片,让我想到每一位地铁上的程序员
- Stack Overflow 遭黑客入侵;中国首条 5G 覆盖地铁诞生;VS Code 1.34 发布!| 极客头条
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Automate This
Christopher Steiner / Portfolio / 2013-8-9 / USD 25.95
"The rousing story of the last gasp of human agency and how today's best and brightest minds are endeavoring to put an end to it." It used to be that to diagnose an illness, interpret legal docume......一起来看看 《Automate This》 这本书的介绍吧!