我们从网络上爬取了2013年到2017年芝加哥每一辆出租车的每一单行程数据,数据内容示例如图一,包含了出租车ID,行程ID,上下车时间,上下车坐标,行程耗时,费用以及支付方式等信息。有了这些数据,我们就可以对其进行数据挖掘分析,找到打车需求最旺的区域和时间段,以便得到更好的出租车资源调度策略等。本案例中我们明确分析目标,要找出2016年里周末10点到18点这个时间段,从奥黑尔国际机场出发的旅客都去了哪儿。深入分析也能从这个分析目标中预测出芝加哥最热门的旅游景点等。
针对该分析目标,我们选择supermap pyspark大数据组件产品,其OD线分析功能即可实现该分析目标,由于OD线分析需要行政区域面数据集,故我们又爬取了芝加哥主要的行政区域面数据。
-
数据
-
工具
supermap-bdtpy-9.1.0-beta
-
步骤
-
数据上传到hdfs,便于分布式计算
./hadoop fs -put /opt/data/*.csv /opt/data/*.meta /taxi_data
-
读取出租车数据,并按条件过滤,提取2016年周末10-18点期间在奥黑尔国际机场上车的行程单
def get_point(): fRdd = read_csv(ss.sparkContext, 'hdfs://localhost:9000/taxi_data/Chicago-Taxi_Trips.csv', SpecFieldNames('', 'TripStartTimestamp', ''), 36, None,'hdfs://localhost:9000/taxi_data/Chicago-Taxi_Trips.meta', None) regionRdd = read_csv(ss.sparkContext, 'hdfs://localhost:9000/taxi_data/Chicago-region.csv', SpecFieldNames('SmID', '', ''), 36, None,'hdfs://localhost:9000/taxi_data/Chicago-region.meta', None) # 奥黑尔国际机场所在的行政区ID为165381 airportRdd = regionRdd.filter(lambda f: int(f.get_value('OBJECTID')) == 165381) # 构造时间周期,2016年里所有的周末,2016-01-02为第一个周六 cycleW = TimeCycle(Duration(1, DurationUnit.Weeks), '2016-01-02 00:00:00', Duration(2, DurationUnit.Days),'2016-01-01 00:00:00', '2017-01-01 00:00:00') tfW = TimeCycleFilter(cycleW) # 构造时间周期,每天的10-18点 cycleH = TimeCycle(Duration(1, DurationUnit.Days), '2016-01-02 10:00:00', Duration(8, DurationUnit.Hours),'2016-01-01 00:00:00', '2017-01-01 00:00:00') tfH = TimeCycleFilter(cycleH) # 上车点数据按时间过滤,过滤行程终点为空的,过滤行程时间异常的,按区域裁剪 fr = fRdd.filter(tfW).filter(tfH).filter(lambda f: f.get_value('TripSeconds') != None).filter(lambda f: f.get_value('DropoffCentroidLatitude') != None).filter(lambda f: f.get_value('DropoffCentroidLongitude') != None).filter(lambda f:int(f.get_value('TripSeconds')) > 120).filter(lambda f:int(f.get_value('TripSeconds')) < 12000).clip(airportRdd.first()) return fr
-
点数据集转属性表数据集,od线分析需要上车点与下车点的关系表数据集
# 构造属性表结构 def make_new_meta(): struct_type = StructType() struct_type.add(StructField('TripID', StringType())) struct_type.add(StructField('TaxiID', StringType())) struct_type.add(StructField('TripSeconds', IntegerType())) struct_type.add(StructField('DropoffCentroidLat', DoubleType())) struct_type.add(StructField('DropoffCentroidLon', DoubleType())) struct_type.add(StructField('PickupCentroidLat', DoubleType())) struct_type.add(StructField('PickupCentroidLon', DoubleType())) return FeatureMetadata(struct_type, 'Empty', None, has_feature_id=True) # 构造新的要素 def make_new_feature(f): xy = str(f.get_value('PickupCentroidLocation')) import re # 提取起始点的xy坐标 x, y = re.findall(r'[(](.*?)[)]', xy)[0].split(" ") field_value = [f.get_value('TripID'), f.get_value('TaxiID'), f.get_value('TripSeconds'), f.get_value('DropoffCentroidLatitude'), f.get_value('DropoffCentroidLongitude'), y, x] # none代表属性表记录,注意参数顺序 return Feature(None, field_value, id_value=f.get_value('TripID'), field_infos=make_new_meta()._get_field_infos()) # 点转属性表 def get_table(): rdd = get_point().rdd.map(lambda f: make_new_feature(f)) tableRdd = FeatureRDD.make(rdd, make_new_meta()) return tableRdd
-
读取用于OD线分析的行政区域面数据
# 用于od线制作的面数据 def get_region(): regionRdd = read_csv(ss.sparkContext, 'hdfs://localhost:9000/taxi_data/Chicago-region.csv',SpecFieldNames('OBJECTID', '', ''), 36, None, 'hdfs://localhost:9000/taxi_data/Chicago-region.meta', None) return regionRdd
-
构建OD线
def make_odline(): # 参与计算的featurerdd必须具备唯一id值 odRdd = make_od_line(get_region(), get_table(), 'NAME', 'PickupCentroidLon', 'PickupCentroidLat', 'DropoffCentroidLon', 'DropoffCentroidLat', 'TripSeconds,Sum,sumTripSeconds') # od线数据 odRdd[0].save_as_csv('hdfs://localhost:9000/taxi_data/output/workday16_line.csv', write_header=True) #od关联区域面数据 odRdd[1].save_as_csv('hdfs://localhost:9000/taxi_data/output/workday16_region.csv', write_header=True) print('Done')
-
-
结果展示,通过idesktop对od分析结果数据集制作专题图表达,可以看出去市区的人最多。
-
感兴趣的伙伴可以进行更多的深度分析,比如不同时间段哪个区域的用车量最大?哪个区域更容易接到长途出租车单?