内容简介:这是涛哥给你推荐的第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 发布!| 极客头条
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序员修炼之道(影印版)
Andrew Hunt、David Thomas / 中国电力出版社 / 2003-8-1 / 39.00
本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视——即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《程序员修炼之道(影印版)》 这本书的介绍吧!