查看原文
其他

一个数据分析的真实失败案例,让我突然有点恍惚了

xiaoyi 小一的学习笔记 2023-01-01

大家好,我是小一

阅读今天的文章之前,一定要认真看完下面这段话

首先,今天分享的内容不同于以往,今天的主题就两个字:失败,还有两个字:真实

刚入职场做数据分析的时候,我基本上隔三差五就会遇到今天的问题,后来经验多了,趟过的坑多了,也就自然而然的不会有这些问题

所以,当这次遇到问题后,突然觉得有点恍惚,我好像又回到了那个不可一世的岁月..


扯远了,下面分享一下我遇到的真实案例:

正文

数据爬取部分

因为做数据分析,会不可避免的需要一些额外的数据,而最简单的方式就是爬虫

像之前分享过的的:爬取用户电话号码标记,以及没有分享过的:爬取 POI 分类、爬取微博某个关键字下的实时舆情 等等都是需要爬虫去搞定数据的。

ok,今天的案例也类似:爬取城市地铁站点数据,以北上广深为例


因为我自己手上已经有了五六七八个百度开发者账号,所以第一时间就想到了 通过百度地图接口 利用 POI 设置地铁分类,然后解析一下数据就行

确实这样是最简单快速的,地图的 POI 分类分的很细致,所以一定会有地铁分类

题外话:关于申请百度开发者账号,创建应用拿到 AK 码这个就不用说了吧,网上一大把的教程

果然,二级分类里面有地铁分类

那,直接通过接口获取就完事了,似乎很简单就能搞定的小任务

接口参数也很简单:query、tag、地区、输出方式和 AK码

构造一下,如果爬取深圳的地铁站点信息 url 应该就这样:

http://api.map.baidu.com/place/v2/search?query=地铁&tag=地铁站&region=深圳&output=json&ak=你的ak

如果要设置翻页的话可以加上:page_size 和 page_num 这两个参数

直接在浏览器里面输入 url,成功获取到数据如下:

ok,接下来设置城市遍历和翻页查找,然后进行 JSON 解析,最后合并数据就可以了。

翻页这个因为已经可以拿到总的数据记录数,所以总页数计算一下就拿到了:

# 计算总页数:sizes是总记录数
pages = int(sizes/20if sizes%20==0 else int(sizes/20)+1

爬虫核心代码如下:

df_result = pd.DataFrame()
for index in range(0, pages):
    print('正在爬取{0}市第 {1}/{2} 页数据'.format(city, index+1, int(sizes / 20) + 1))
    url = 'http://api.map.baidu.com/place/v2/search?query=地铁&region={0}&output=json' \
    '&page_size=20&page_num={1}&ak=你的ak'.format(city, index)
    res = requests.get(url, headers={'User-Agent': get_ua()})
    data = json.loads(res.text)
    if data["total"] > 0:
        df_data = pd.DataFrame(data["results"])
        df_data['lat'] = df_data['location'].apply(lambda x: x['lat'])
        df_data['lng'] = df_data['location'].apply(lambda x: x['lng'])
        df_data['cnts'] = df_data['address'].apply(lambda x: len(x.split(";")))
        df_data.drop('location', axis=1, inplace=True)
        df_data.rename(columns={'name''站点名称''address''线路名称''province''省份名称''city''城市名称','area''行政区名称''detail''细节''uid''uid''lat''经度''lng''纬度','cnts''换乘站点'}, 
                       inplace=True)
        df_data = df_data[['站点名称''线路名称''省份名称''城市名称''行政区名称''细节',  'uid''经度''纬度''换乘站点']]
        df_result = df_result.append(df_data)

最终数据集如下:


数据清洗部分

爬完数据,当然需要对数据做一些清洗了

先来看下整体数据:

一共 591 条数据,表示有 591 个地铁站点,每个站点都有 10 个详细的字段介绍。

另外,换乘站点列是在爬虫阶段已经做好的数据处理,表示一个地铁站有多少个换乘站。计算的依据是:如果线路名称中出现多个地铁路线,则对应的表示有多个换乘站。

对了,最后的几条数据有垃圾数据。很明显的能够看到,出现的并不是地铁xx线,而是相关地址信息。

用正则过滤一下再说:

df_data_1 = df_data.copy()
# 通过contains方法进行过滤
df_data_1 = df_data_1[df_data_1['线路名称'].str.contains('地铁.+线|APM线|磁悬浮|机场线')]
# 异常站点数据
df_data_error = df_data[~df_data['线路名称'].isin(df_data_1['线路名称'].tolist())]
df_data_error.sample(10)

另外,还有一个需要手动过滤一下,这也是数据没清洗干净后面分析的时候才发现的

df_data_1[df_data_1['站点名称']=='AED(浦东新区龙阳路地铁站)']

删掉异常的之后,数据少了 29 条,只剩下 561 条


数据分析部分

数据分析部分能做的事就多了,最简单的例如:北上广深哪个城市地铁站点最多?哪个城市的地铁路线最多?换乘站点最多的是几站换乘?分别又是哪几个站? 

难一点的像:计算距离,比如二手房距离地铁站的最近距离,地铁站点之间的平均距离等等。

先来分析一下四个城市的地铁站点数量,直接做一个分析统计图就行

代码也很简单:

"""查看城市的地铁站点数量"""
df_city = df_data_1.groupby('城市名称')
df_city_cnt = pd.DataFrame()
df_city_cnt['metro_cnt'] = df_city['城市名称'].count()
df_city_cnt = df_city_cnt.reset_index()
df_city_cnt

绘图如下:

联立每个城市的具体地铁线路数,再来看一下:

这里面有一些代码小技巧可以学一下

"""查看每个城市的地铁线路个数"""
df_metro = df_data_1[df_data_1['换乘站点']==1].groupby('城市名称')
df_metro_cnt = pd.DataFrame()
df_metro_cnt['lines_cnt'] = df_metro['线路名称'].apply(lambda x:len(x.unique()))
df_metro_cnt = df_metro_cnt.reset_index()

绘图如下:

看起来四个城市的差别不是很大(埋下了伏笔

我们知道:如果一个城市的轨道交通很发达,那肯定对应的换乘站点会很多,甚至会有一些超级交通枢纽。

来看下具体每个城市的换乘站点情况:

绘图如下:

由图可知,深圳和上海都拥有四站换乘站点,其中深圳有 1个,上海有 3个

不愧是新崛起的超一线城市,看四站换乘就能看出一二。

对应的,四站换乘的地铁站分别是:深圳的车公庙站,上海的世纪大道站、龙阳路站和曹杨路站

针对深圳市再进行 深度分析:先来看深圳市各区域的站点数量

代码如下:

"""查看城市的地铁站点数量"""
df_data_sz = df_data_1[df_data_1['城市名称']=='深圳市']
df_sz_area= df_data_sz.groupby('行政区名称')
df_sz_area_cnt = pd.DataFrame()
df_sz_area_cnt['area_cnt'] = df_sz_area['城市名称'].count()
df_sz_area_cnt = df_sz_area_cnt.reset_index()
df_sz_area_cnt

绘图如下:

其中,龙岗区由于面积较大,虽然不是市中心,但是区域内站点数量仍然排名第一(又一个伏笔

其次是罗湖区28个站点、福田区23个站点

接着,通过地图看一下具体的分布

这一块有两种方法:excel 的三维地图和 pyecharts

excel 里面用的 GPS 经纬度,而百度接口给的都是百度经纬度

用 excel 绘图需要转一下经纬度,搞定之后的三维地图长这样:

这个图,我是越看越不对,越不对越看

然后,发现了这个:

很明显,少数据了,少了很多很多,如果不是绘图,很难发现中心区域的数据少这么多。

那也就是说,从爬虫拿到的数据,再到数据清洗以及后面的简单分析,结果都是有问题的,有偏向性的。

确实是,你用了局部数据分析得出的结论,去分析评估整体?对不起,你的结果不具备整体支撑性

不具备支撑性的结果,只能说是:辣鸡结果

到此,翻篇,从头开始


总结一下

上面的案例,如果你没有做可视化这部分,或者没仔细看,那真有可能就完结然后做下一环节了。

对于爬虫来说,能爬到数据很重要,但是没有检验过的数据就像垃圾一样,做出来的东西自然也就好不到哪去

再回到案例中,有很多种检验方法,例如直接去地铁官网确认一下轨道交通信息,去百度搜一下总站点数量等,就可以轻松的避免后面的麻烦

最后,我重新搞了一份数据,也成功做出来了图,长下面这样:

差别挺大的!


虽然本次分析失败了,但是案例里面通过百度API 爬取数据的方法你需要学习一下,想必以后做数据分析少不了。

但是一定要记得验证你爬取的数据!!!

文中的爬虫源码也分享出来,还是老规矩,加小一微信(ID:zhiqiuxiaoyi)领取



往期文章



数据探索分析就写了6000+的实战文,写完怕不得几万字?

2021-04-08

数据清洗最基础的10个问题,基本涵盖目前常见的数分场景!

2021-03-30

一键爬取基金历年季度报数据,轻松搞定!附源码

2021-02-20


我是小一,坚持向暮光所走的人,终将成为耀眼的存在!

期待你的 连!我们下节见

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存