上海市地铁刷卡数据到OD矩阵

  • 前言
  • 思路
  • 结果预览
  • 代码
  • 代码解读
  • 改进思路
  • 改进代码
  • 代码解读
  • 完整代码
  • 参考文献

前言


接上期 ,定义出早高峰和晚高峰时段,接下来就是要分早高峰和晚高峰来做出上海市地铁刷卡人次OD矩阵(origin-destination matrix),因为上海轨道交通具有很好的连通性,所以我们可以利用抽象的矩阵理论来分析。这样整个上海市轨道交通的通勤OD情况就能够通过一个矩阵来表示和研究,矩阵中的元用来刻画各站点的客流来源和去向。

思路

首先要定义出地铁OD矩阵和矩阵中的元,定义
A = ( a i j ) A=(a_{ij}) A=(aij​)
为上海市地铁OD矩阵,矩阵中的元 a i j a_{ij} aij​定义为同一时段从第 j j j个站到第 i i i个站的刷卡人次,比如令 i i i为人民广场站, j j j为富锦路,此时 a i j a_{ij} aij​就表示相同时段内从富锦路进站,从人民广场出站的那波人,令 j j j取不同时值时候,同样也可以知道其他站点到人民广场站的刷卡人次,同理也可以令 i i i为其他站点,这样令 i i i和 j j j取不同的值时,就知道不同站点进出和特定流向情况,现在的问题是如何度量 a i j a_{ij} aij​大小。这里给出集合论方法,令
A = { 卡 号 : j 进 站 的 卡 号 } A=\{卡号: j进站的卡号\} A={卡号:j进站的卡号}
B = { 卡 号 : i 出 站 的 卡 号 } B=\{卡号:i出站的卡号\} B={卡号:i出站的卡号}
因为一个卡号对应一个人,集合 A A A表示从 j j j站进来的那波人次,集合 B B B表示从 i i i站出来的那波人次,如果两拨人次重复的,那么重复的那小波人次就是第 j j j个站到第 i i i个站的刷卡人次 则,此时集合 A A A和集合 B B B的交集 A ∩ B A\cap B A∩B 表示从 j j j 进站的且从 i i i 出站的卡号, 即交集 A ∩ B A\cap B A∩B的势便是 a i j a_{ij} aij​的取值。

结果预览

代码

# -*- coding: utf-8 -*-
"""
project_name:read_mysql
@author: 帅帅de三叔
Created on Thu Dec 12 15:10:32 2019
"""
import numpy as np #导入数值分析模块
import pandas as pd #导入数据分析模块
from sqlalchemy import create_engine #数据库引擎
connection=create_engine("mysql+pymysql://root:123456@localhost:3306/metro_sh?charset=utf8") #连接数据库
sql=pd.read_sql('zaogaofeng',connection) #读取sql数据库
df=pd.DataFrame(sql) #数据框化
#print(df.head()) #测试表头前5
stations=df['站点'].unique() #所有去重的站点
M=np.zeros(shape=(313,313)) #构造一个313*313零矩阵for index1,i in enumerate(stations): #行for index2,j in enumerate(stations): #列card_out_i=df[(df['站点']==i)&(df['费用']!=0)]['卡号'] #第i站出站卡号序列card_in_j=df[(df['站点']==j)&(df['费用']==0)]['卡号'] #第j站进站卡号print(len(card_out_i),len(card_in_j)) #测试j进站,i出站的卡号ai=set(card_out_i) #出站列表集合化aj=set(card_in_j)  #进站列表集合化aij=ai.intersection(aj) #求交集,即从j进站,i出站的卡号print(len(aij)) #交集计数count=len(aij) M[index1,index2]=count #赋值
M=pd.DataFrame(M) #数据框化
M.columns=stations #构造表头
M.index=stations #构造索引
M.to_excel("早高峰OD矩阵.xlsx") #写入excel

代码解读

整段代码大体过程是先用sqlalchemy模块的create_engine类连接到MySQL数据库,紧接着用 pd.read_sql() 读取库里面的数据表,比如这里的zaogaofeng,数据读出来了,接下来就完全是python操作了,如提取不重复的站点,用 card_out_i=df[(df[‘站点’]==i)&(df[‘费用’]!=0)][‘卡号’] 筛出第 i i i 站出站卡号序列,用 card_in_j=df[(df[‘站点’]==j)&(df[‘费用’]==0)][‘卡号’] 筛出第 j j j 站出站卡号序列,然后用set() 函数集合化,并求交集和交集的势,并把所求的结果赋值给先定义的零矩阵M的第 i i i行第 j j j列元 a i j a_{ij} aij​,最后把重新赋值后的矩阵写入到excel便得到想要得OD矩阵。

改进思路

首先,代码运行太慢了,不管是读取数据库MySQL还是构造OD矩阵中的多两层循环还是集合筛选运算,都很费时;其次是代码写的太散,通用性不强,想打包成函数或者类。下面以晚高峰为例,利用面向对象编程和模块化思想,看看代码是不是简洁些,运行时间多少?

改进代码

# -*- coding: utf-8 -*-
"""
project_name:read_mysql
@author: 帅帅de三叔
Created on Thu Dec 12 15:10:32 2019
"""
import time
import numpy as np #导入数值分析模块
import pandas as pd #导入数据分析模块
from sqlalchemy import create_engine #数据库引擎
connection=create_engine("mysql+pymysql://root:123456@localhost:3306/metro_sh?charset=utf8") #连接数据库
sql=pd.read_sql('wangaofeng',connection) #读取sql数据库
data=pd.DataFrame(sql) #数据框化
print(data.head()) #测试表头前5def generate_od_matrix(df): #自定义构造OD矩阵函数stations=list(df['站点'].unique()) #所有去重的站点,object类型转listOD_Matrix=np.zeros(shape=(len(stations),len(stations))) #构造一个313*313零矩阵for index1,i in enumerate(stations): #行for index2,j in enumerate(stations): #列print(i,j)card_out_i=df[(df['站点']==i)&(df['费用']!=0)]['卡号'] #第i站出站卡号序列card_in_j=df[(df['站点']==j)&(df['费用']==0)]['卡号'] #第j站进站卡号print(len(card_out_i),len(card_in_j)) #测试j进站,i出站的卡号ai=set(card_out_i) #出站列表集合化aj=set(card_in_j)  #进站列表集合化aij=ai.intersection(aj) #求交集,即从j进站,i出站的卡号print(len(aij)) #交集计数count=len(aij) #统计j进站,i出站的刷卡人次OD_Matrix[index1,index2]=count #赋值M=pd.DataFrame(OD_Matrix) #数据框化M.columns=stations #构造表头M.index=stations #构造索引M.to_excel("晚高峰OD矩阵.xlsx") #写入excel  if __name__=="__main__": #起始主函数start_time=time.time() #开始时间generate_od_matrix(data)end_time=time.time() #结束时间print("the process lasts:",end_time-start_time) #程序运行总时间

代码解读

整个程序跑了20989秒,近6个小时,要知道这才是晚高峰80分钟的时间跨度,150万条刷卡记录,如果换成一天的就是900万条,大约35小时,关键怎么在电脑上快速读取这么大数据和处理,这就是接下来要研究的问题了。为此,从新整理了代码,写了两个函数,第一个函数 read_mysql 用来读取MySQL得到一个数据框,第二个函数 generate_od_matrix调用第一个函数的结果来生成OD矩阵,最后主函数用来保存OD矩阵到excel中,本机配置如下

程序是从周一下午4点左右开跑的,周三早上来上班,发现程序跑完了,甚是欣慰,总共花了137036.9512345791秒,大约是38小时,比计划中的多3小时,这也是可以理解的,其实读数据大约只要30分钟,大部分时间是花在遍历数据并集合化处理上面。

完整代码

# -*- coding: utf-8 -*-
"""
project_name:read_ten_million_rows_data_from_mysql
@author: 帅帅de三叔
Created on Fri Dec 20 13:19:18 2019
"""
import time #导入时间模块
import numpy as np #导入数值分析模块
import pandas as pd #导入数据分析模块
import pymysql #导入数据库连接模块 def read_mysql(): #定义读取MySQL函数rows=[] #用来存放行数据db=pymysql.connect(host='localhost',user="root",passwd="123456",database="metro_sh",port=3306,charset='utf8',cursorclass =pymysql.cursors.SSCursor) #连接到本地MySQL数据库cursor=db.cursor() #获取游标cursor.execute("SELECT * FROM metro20160901") #筛取数据 while True:row=cursor.fetchone() #一次只取一行rows.append(row)print("正在读取第%d行"%len(rows))print(row)if not row:breakcursor.close() #关闭游标db.close() #关闭数据库连接df=pd.DataFrame(rows)return dfdef generate_od_matrix(df): #定义生成od矩阵的函数df.columns=["卡号","日期","时间","站点","方式","费用","是否有优惠"] #重命名表头stations=df['站点'].unique() #所有去重的站点 od_matrix=np.zeros(shape=(len(stations),len(stations))) #构造一个313*313零矩阵for index1,i in enumerate(stations): #行for index2,j in enumerate(stations): #列print(index1,index2)card_out_i=df[(df['站点']==i)&(df['费用']!=0)]['卡号'] #第i站出站卡号序列card_in_j=df[(df['站点']==j)&(df['费用']==0)]['卡号'] #第j站进站卡号print(len(card_out_i),len(card_in_j)) #测试j进站,i出站的卡号ai=set(card_out_i) #出站列表集合化aj=set(card_in_j)  #进站列表集合化aij=ai.intersection(aj) #求交集,即从j进站,i出站的卡号print(len(aij)) #交集计数count=len(aij) od_matrix[index1,index2]=count #赋值               od_matrix=pd.DataFrame(od_matrix) #数据框化   return od_matrix,stationsif __name__=="__main__":start_time=time.time() #开始时间M,stations=generate_od_matrix(read_mysql()) #函数嵌套调用读取数据库函数M.columns=stations #构造表头M.index=stations #构造索引M.to_excel("上海市OD矩阵.xlsx") #写入excel  end_time=time.time() #开始时间print('程序耗时:',end_time-start_time) #测试读取数据时间

如果你不会写代码或直接只想要数据的话可以关注“三行科创”公众号,在对话框留个邮箱和所要数据名称,我发给你。

参考文献

1,https://wenku.baidu.com/view/165abf1d336c1eb91a375d8d.html
2,https://wenku.baidu.com/view/fa71f2107375a417866f8f81.html?sxts=1575956307792
3,https://wenku.baidu.com/view/5710cba20d22590102020740be1e650e52eacf23.html?rec_flag=default&sxts=1575957393812

上海市地铁刷卡数据到OD矩阵相关推荐

  1. 一种基于蜂窝信令数据的数据驱动型OD矩阵构建的方法:以里昂地区(法国)作为研究...

    文章信息 本周阅读的论文是题目为<A data‑driven approach for origin–destination matrix construction from cellular ...

  2. TransCad导入Excel中的OD矩阵和PA数据

    目录 前言 准备工作 路线层 小区层 导入数据 PA数据导入 OD 矩阵数据导入 写在最后 前言 在进行tc上机练习时,老师给的题目是几张图片,里面包含了小区的未来PA,和现状OD等数据.如果小区数据 ...

  3. 【OD矩阵】《城市公交IC卡·数据分析方法及应用》基于ICAVL数据的上车站点识别

    <城市公交IC卡·数据分析方法及应用> 陈学武.李海波.候贤耀著 <城市公交IC卡·数据分析方法及应用>基于IC&AVL数据的上车站点识别·笔记 算法基本思路: 此处算 ...

  4. 【OD矩阵】《城市公交IC卡·数据分析方法及应用》基于换乘点的上车点识别

    <城市公交IC卡·数据分析方法及应用> 陈学武.李海波.候贤耀著 <城市公交IC卡·数据分析方法及应用>--基于换乘点的上车点识别·笔记 换乘点 通常情况下,公交乘客总是选择步 ...

  5. 大数据早报:时装设计也用上了人工智能,亚马逊研究出新算法;上海地铁趣味消费数据发布(9.12)

    数据早知道,上乐投网看早报! 『MongoDB』MongoDB再遭大规模勒索!这可能最全面的数据库防勒索方案 又一起数据库被劫持勒索事件.MongoDB 数据库又双叒叕被攻击了,三个黑客团伙劫持了 2 ...

  6. Byte学堂:公交GPS及IC卡数据原理及分析方法

    公交数据是指公交在营运过程中产生的交易.车辆运行等数据,通过对公交大数据进行深入的分析和挖掘,可以有效地监控城市道路交通运作状况及公交系统运营状况,及时.合理发现问题,调度交通资源,提高公交运力,缓解 ...

  7. 上海一百多个数据中心每年消耗全市1.6%的电,将优胜劣汰

    在信息化时代,我们每天的工作和生活都离不开数据.可你知道,遍布城市的互联网数据中心,每年会消耗多少能源吗? 互联网数据中心,简称IDC(Internet Data Center),是数据汇聚.存储.计 ...

  8. python读取csv某一列存入数组_python 读取.csv文件数据到数组(矩阵)的实例讲解

    利用numpy库 (缺点:有缺失值就无法读取) 读: import numpy my_matrix = numpy.loadtxt(open("1.csv","rb&qu ...

  9. 【论文复现与改进】针对弱标注数据多标签矩阵恢复问题,改进后的MCWD算法,让你的弱标注多标签数据赢在起跑线上

    改进后的MCWD算法,让你的弱标注多标签数据赢在起跑线上 前言 MCWD算法 算法展示 算法改进 实现代码 实验结果 总结 前言 最近刷完了李航老师的<统计学习与方法>,手痒到又想复现几个 ...

最新文章

  1. Python 标准库之 datetime
  2. 1. python 字符串简介与常用函数
  3. BigData之matplotlib:爬虫2018年福布斯中国富豪榜进行数据统计分析,大数据告诉你一些不可思议的事情
  4. poj 2112 Optimal Milking(二分+Floyd+最大流)
  5. 4、已知圆的半径radius= 1.5,求其面积
  6. SAP CRM WebClient UI的工作中心加载逻辑
  7. angualarjsdemo
  8. HTML文件上传对象file
  9. php试题与答案(二),php面试题附答案二
  10. Android ListView使用
  11. 【吴恩达课后编程作业pytorch实现】Keras入门与残差网络的搭建【1】
  12. 破解成功!iMac成功运行WindowsXP系统
  13. cif t t操作流程图_Danish:STATA 操作正态检验、卡方检验和T检验
  14. The North American Invitational Programming Contest 2016 - Tourists ( LCA )
  15. 阿里云的ACP认证与ACE认证含金量高吗?
  16. 优秀的人都在读的10本好书!
  17. checkstyle 行内含有制表符tab,缩进符数量不正确
  18. golang 枚举 iota
  19. 【璟丰机电】美国派克Parker产品在FPD中的行业应用案例盘点
  20. 【JavaScript】 模块 module

热门文章

  1. MATLAB save函数
  2. 相邻块(数细胞)问题之BFS解
  3. P4415 [COCI2006-2007#2] KOLONE 题解
  4. 极客时间高级Java工程师体系课2.0
  5. Kimball 维度建模技术 (1)
  6. Mariadb数据库集群设计实验
  7. 在线生成艺术字、图片、印章等网站大集合
  8. Live555 直播源 以及MediaSubsession
  9. RxJS学习笔记之Subject
  10. 使用域名转发mqtt协议,避坑指南