990万次骑行:纽约自行车共享系统分析

star2017 1年前 ⋅ 6609 阅读

2016102201

Citi Bike是纽约市在2013年5月27日启动的一项自行车共享计划,由“花旗银行”(Citi Bank)赞助并取名为“花旗单车”(Citi Bike)。在曼哈顿,布鲁克林,皇后区和泽西市有8,000辆自行车和500个车站。为纽约的居民和游客提供一种方便快捷,并且省钱的出行方式。

2016102202

人们随处都能借到Citi Bank,并在他们的目的地归还。使用Citi Bank的方法很简单,购买会员资格,然后在附近查找可以使用的Citi Bank,使用会员key解锁,在有效时间内(30或45分钟)归还并锁定Citi Bank。由于每个Citi Bank的租赁站点都有GPS位置信息,因此可以记录到用户租赁和骑行过程中的数据。“Citi Bank”官网提供了用户每一次骑行的数据,包括租赁开始及结束的位置及时间,整个骑行过程的时间,自行车ID,以及用户的性别和出生日期等数据。我们将使用python对“Citi Bank”2015年的数据进行分析,以了解纽约自行车共享计划的情况。并回答诸如谁在使用Citi Bike他们什么时间开始骑行每次骑行的时间和距离,以及哪些骑行线路最受欢迎等问题。

开始前的准备工作

首先我们将需要使用的库文件导入到python中,这里包括numpy,pandas,datetime和用于数据可视化的pyplot,后面根据不同的分析方向我们还会陆续导入其他的库文件。

1

2

3

4

5

6

importnumpy as np

importpandas as pd

importtime,datetime

importmatplotlib.pyplot as plt

#读取Citi Bike的数据并创建数据表

cb1=pd.DataFrame(pd.read_csv('201501-citibike-tripdata.csv'))

Citi Bike的数据是按月存储的,因此我们需要逐月读取并将各个月份的数据进行拼接。

1

2

3

4

5

#对导入的数据表进行拼接,汇总后的数据表名为cb

cb=cb1.append(cb2,ignore_index=False)

#查看数据表维度

cb.shape

(9937969,15)

2015年Citi Bike数据共包含993万行,15列数据。其中每一行数据都代表一次“Citi Bank”的租借和骑行记录。

惊人的990万次骑行

2016102203

我们首先对2015年“Citi Bank”的数据中的几个关键指标进行统计,在一年中共有497个租赁点,也就是车站,8477辆自行车被使用。自行车的使用次数更是高达993万次,平均算下来每辆自行车每天被租借3.21次。可见人们对“Citi Bank”的热情。而每次的骑行时间平均为16.13分钟。

2016102204

以下为每个关键指标的统计代码和结果。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#唯一租赁点数量计数

len(cb['start station name'].unique())

497

#唯一自行车ID计数

len(cb['bikeid'].unique())

8477

#骑行次数计数

cb['starttime'].count()

9937969

#每辆自行车租借频率

cb['bikeid'].count()/len(cb['bikeid'].unique())

1172.3450513153239

#每辆自行车每日租借频率

cb['bikeid'].count()/len(cb['bikeid'].unique())/365

3.2119042501789696

#每次租借平均时长(分钟)

cb['tripduration'].sum()/cb['bikeid'].count()/60

16.134794237132358

2016102205

2015年的Citi Bike的使用量整体趋势由低到高,2月Citi Bike的使用量最低,然后使用量逐月增长,直到9月出现使用量最高值。11月使用量开始下降。这可能是由于季节和气温因素导致的。我们下面按季度对骑行数据进行汇总并进行对比。

以下是按月汇总骑行数据并汇总折线图的代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

#对starttime设置日期格式

cb['starttime']=pd.to_datetime(cb['starttime'])

#将starttime设置为数据表索引

cb=cb.set_index('starttime')

#按月对骑行数据进行计数

cb_month=cb.resample('M',how=len)

#提取汇总后的bikeid字段

group_cb_month=cb_month['bikeid']

#汇总按月汇总的骑行次数折线图

plt.rc('font', family='STXihei', size=15)

a=np.array([1,2,3,4,5,6,7,8,9,10,11,12])

plt.plot(group_cb_month,'g8',group_cb_month,'g-',color='#39A2E1',linewidth=3,markeredgewidth=3,markeredgecolor='#39A2E1',alpha=0.8)

plt.xlabel('月份')

plt.ylabel('租赁骑行次数')

plt.title('2015年Citi Bike每月骑行次数')

plt.grid( color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.xticks(a, ('1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月') )

plt.show()

2016102206

从2015年四个季度的数据来看,用户对Citi Bike的使用受季节因素的影响,第一季度气温最低,Citi Bike的使用量也较低。第二季度第三季度为夏秋交替,使用量最高。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#按季度对骑行数据进行计数

cb_quarterly=cb.resample('Q',how=len)

#提取按季度汇总后的bikeid字段

group_cb_quarterly=cb_quarterly['bikeid']

#绘制按季度汇总的骑行次数柱状图

plt.rc('font', family='STXihei', size=15)

a=np.array([1,2,3,4])

plt.bar([1,2,3,4],group_cb_quarterly,color='#39A2E1',alpha=0.8,align='center',edgecolor='white')

plt.xlabel('季度')

plt.ylabel('租赁骑行次数')

plt.title('2015年Citi Bike每季度骑行次数')

plt.legend(['次数'], loc='upper right')

plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.xticks(a,('一季度','二季度','三季度','四季度'))

plt.show()

哪些人在使用Citi Bike

2016102207

我们很好奇993万次骑行这个庞大的数据后面是哪些人在使用Citi Bike。由于获得的数据中只有用户性别,出生日期和会员类别的数据,因此我们仅从这三个维度对Citi Bike的用户进行简单的描述。

66%的男性用户使用Citi Bike

2015年使用Citi Bike服务的用户中,66%为男性用户,女性用户的占比为20%,另外还有13%的用户性别未知。这让我想起了北京自重25公斤的共享单车。

2016102208

以下是计算用户性别占比和绘制饼图的代码。

1

2

3

4

5

6

7

8

9

10

#按用户性别进行汇总并计算不同性别的占比

user_gender=cb.groupby('gender')['bikeid'].agg(len)/cb["bikeid"].count()*100

#汇总用户性别占比饼图

plt.rc('font', family='STXihei', size=15)

colors=["#052B6C","#39A2E1","#EA1F29"]

name=['未知','男性','女性']

plt.pie(user_gender,labels=name,colors=colors,explode=(0,0,0),startangle=60,autopct='%1.1f%%')

plt.title('Citi Bike用户性别占比')

plt.legend(['未知','男性','女性'], loc='upper left')

plt.show()

30-50岁用户热衷于骑行

我们将Citi Bike的用户年龄分为四组,0-18岁为少年组,18-30岁为青年组,30-50岁为中年组,50岁以上为老年组。其中少年组的租借和骑行次数最少,中年组的租借和骑行次数最高,其次为青年组。50岁以上的老年组也有相当数量的记录。

2016102209

以下是对用户年龄分组和汇总柱状图的代码,用户年龄由出生日期和当前年份计算得出,其中包含部分极端值。

1

2

3

#查看出生日期的范围

cb['birth year'].min(),cb['birth year'].max()

(1885.0,1999.0)

这里1885年很怪异,按照这个出生日期,2016年时用户的年龄已经达到了131岁。我们不知道其中的具体原因,但由于Citi Bike整体的数据较为规范不需要清洗,因此我们选择保留这个值。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

#使用2015年与用户出生日期计算年龄

cb['age']=2015-cb['birth year']

#用户最小年龄17岁,最大年龄131岁

cb['age'].min(),cb['age'].max()

(17.0,131.0)

#对用户年龄进行分组

bins=[0,18,30,50,131]

group_age=['少年','青年','中年','老年']

cb['group_age']=pd.cut(cb['age'], bins, labels=group_age)

#按年龄分组对数据进行汇总

user_age=cb.groupby('group_age')['group_age'].agg(len)

#生成用户年龄分布柱状图

plt.rc('font', family='STXihei', size=15)

a=np.array([1,2,3,4])

plt.bar([1,2,3,4],user_age,color='#052B6C',alpha=0.8,align='center',edgecolor='white')

plt.xlabel('年龄分组')

plt.ylabel('租赁次数')

plt.title('Citi Bike用户年龄分布')

plt.legend(['次数'], loc='upper right')

plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.xticks(a,('少年','青年','中年','老年'))

plt.show()

86%的用户为年费会员

Ctii Bike对纽约本地居民,短期停留和游客提供了三种会员期限选择,按Citi Bike官网的推荐,年度会员适合于本地居民,也是最划算的一种租赁方式。3天的会员适合于短期停留或居住的用户,1天的会员适合于游客。因此我们也可以按不同的会员期限反向推断用户的身份。

2016102210

在2015年的数据表中,1天和3天的会员统称为Customer,年度会有成为Subscriber。从下面的占比数据中可以看出,绝大部分Citi Bike的用户为年度会员,占比高达86%。反向推测绝大部分用户为纽约本地常住居民。

2016102211

以下为计算用户会员类别和汇总饼图的代码。

1

2

3

4

5

6

7

8

9

10

#按用户的会员类别进行汇总并计算占比

user_type=cb.groupby('usertype')['bikeid'].agg(len)/cb["bikeid"].count()*100

#汇总用户会员类别饼图

plt.rc('font', family='STXihei', size=15)

colors=["#EA1F29","#39A2E1"]

name=['Customer','Subscriber']

plt.pie(user_type,labels=name,colors=colors,explode=(0,0),startangle=43,autopct='%1.1f%%')

plt.title('Citi Bike用户类别占比')

plt.legend(['Customer','Subscriber'], loc='upper left')

plt.show()

用户的骑行时间及速度

2016102212

在993万次骑行的数据背后,是否存在一些规律我们选择了5月(春季)的数据对用户使用Citi Bike的行为进行了统计和分析,这里既包括使用Citi Bike的时间,也包括骑行速度,热门租赁站点和骑行线路。

每日早晚是使用高峰

2016102213

Citi Bike的使用者大部分为城市居民,少部分为游客。在一天中的上午7点—8点和下午的5点—6点是Citi Bike的使用高峰。这两个时间正好是上下班的高峰时间。除此之外中午12点—下午4点也有较高的使用量。

以下是24小时使用趋势和绘制折线图的代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#读取5月数据并创建数据表

cb5=pd.DataFrame(pd.read_csv('201505-citibike-tripdata.csv'))

#对starttime字段进行分列

time_split=pd.DataFrame((x.split(' ')forxincb5.starttime),index=cb5.index,columns=['start_date','star_time'])

#对分列后的表与原数据表进行拼接

cb5=pd.merge(cb5,time_split,right_index=True, left_index=True)

#更改star_time字段为日期格式

cb5['star_time']=pd.to_datetime(cb5['star_time'])

#设置star_time为表索引

cb5=cb5.set_index('star_time')

#按小时对数据进行汇总

star_hour=cb5.resample('H',how=len)

#提取按小时汇总的bikeid数据

ride_hour=star_hour["bikeid"]

#绘制24小时折线图

plt.rc('font', family='STXihei', size=15)

a=np.array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23])

plt.plot(ride_hour,'8',ride_hour,'g-',color='#052B6C',linewidth=3,markeredgewidth=3,markeredgecolor='#052B6C',alpha=0.8)

plt.xlabel('24小时')

plt.ylabel('租赁次数')

plt.title('Citi Bike用户24小时租赁次数')

plt.grid( color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.xticks(a, ('0','','','','','5','','','','','10','','','','','15','','','','','20','','','') )

plt.show()

骑行时间多在20分钟以内

2016102214

在骑行时间方面,按照不同的会员类别Citi Bike对时间有不同的限制,1天和3天会员每次骑行的限制时间为30分钟,超过30分钟每增加15分钟收费4美金。年度会有每次骑行限制时间为45分钟,超出10分钟收费2.5美金,再次超出逐级收费。Citi Bike鼓励用户短途使用并且在接近限制时间时重新租赁新的自行车,避免产生超时费用,并且提高自行车的周转率。

我们对5月份用户的骑行时间进行处理和分组,通过下面的图表可以看出大部分用户的使用时间为10-20分钟。其次为30分钟和5分钟以内。超过30分钟的使用次数较少。即使在86%的用户为年度会员的情况下,使用时间在30-45分钟的情况也较少。由此推测大部分的骑行为短途。

2016102215

以下为骑行时间分组和绘制柱状图的代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#对骑行时间进行分组

bins=[0,300,600,1200,1800,2700,2825827]

#为每个分组命名

group_tripduration=['5分钟','10分钟','20分钟','30分钟','45分钟','更长时间']

#在原数据表中增加时间分组字段

cb5['group_tripduration']=pd.cut(cb5['tripduration'], bins, labels=group_tripduration)

#按分组对数据进行汇总计数

group_minute=cb5.groupby('group_tripduration')['group_tripduration'].agg(len)

#汇总骑行时间分组柱状图

plt.rc('font', family='STXihei', size=15)

a=np.array([1,2,3,4,5,6])

plt.bar([1,2,3,4,5,6],group_minute,color='#9F713F',alpha=0.8,align='center',edgecolor='white')

plt.xlabel('时间分组')

plt.ylabel('骑行次数')

plt.title('Citi Bike骑行时间分布')

plt.legend(['时间'], loc='upper right')

plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='y',alpha=0.4)

plt.xticks(a,('5分钟','10分钟','20分钟','30分钟','45分钟','更长时间'))

plt.show()

平均骑行速度6.3公里/小时

2016102216

在Citi Bike的数据表中并没有直接提供每次骑行的速度数据,但包含了每个开始和结束站点的经纬度坐标。我们通过这些坐标计算出了两个站点间的距离,并匹配到对应的骑行中。在经过与本次骑行所耗费的时间计算出这次骑行的平均速度。通过对5月的数据进行处理,用户的平均骑行速度为6.3公里/小时。

以下是计算骑行速度的代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

#导入库文件

frommathimportradians, cos, sin, asin, sqrt

importnumpy as np

importpandas as pd

#通过经纬度计算距离的函数

defhaversine(lon1, lat1, lon2, lat2):# 经度1,纬度1,经度2,纬度2 (十进制度数)

"""

Calculate the great circle distance between two points

on the earth (specified in decimal degrees)

"""

# 将十进制度数转化为弧度

lon1=map(radians, np.array(lon1))

lat1=map(radians, np.array(lat1))

lon2=map(radians, np.array(lon2))

lat2=map(radians, np.array(lat2))

lon1=np.array(list(lon1)).reshape(-1,1)

lon2=np.array(list(lon2)).reshape(-1,1)

lat1=np.array(list(lat1)).reshape(-1,1)

lat2=np.array(list(lat2)).reshape(-1,1)

# haversine公式

dlon=lon2-lon1

dlat=lat2-lat1

a=np.sin(dlat/2)**2+np.cos(lat1)*np.cos(lat2)*np.sin(dlon/2)**2

c=2*np.arcsin(np.sqrt(a))

r=6371# 地球平均半径,单位为公里

returnc*r*1000

#计算每次骑行的米数并增加骑行距离字段

cb5["meter"]=haversine(cb5["start station longitude"],cb5["start station latitude"],cb5["end station longitude"],cb5["end station latitude"])

#将原数据表中的骑行时间由秒转化为小时

cb5["duration_hour"]=cb5["tripduration"]/3600

#将米转化为公里并与小时计算出速度

cb5["speed"]=cb5["meter"]/1000/cb5["duration_hour"]</pre>

现在我们有了每次骑行的速度,还需要计算出用户平均的骑行速度。

1

2

3

4

5

6

7

8

9

10

</pre>

<pre>#将每次骑行的米数求和并转化为公里

km=cb5["meter"].sum()/1000

#将每次骑行的秒数求和并转化为小时

hour=cb5["tripduration"].sum()/3600

#计算平均速度

speed=km/hour

#平均速度为6.31公里/小时

speed

6.3101247093495</pre>

骑行与气温是否存在关联

2016102217

在990万次骑行中,第一季度用户对Citi Bike的使用量最低,第三季度使用量最高。有明显的季节因素。下面我们导入纽约市2015年的气象数据,来看下天气因素与Citi Bike间是否存在关联,并试着用天气的变化来预测Citi Bike的使用量。

2016102218

绘制每日最高气温与Citi Bike使用量的散点图,从图中可以发现Citi Bike的使用量与日最高气温间呈正相关,随着日最高气温的增长Citi Bike的使用量也在逐渐增长。接下来我们通过回归分析发现最高气温与Citi Bike间的R平方值为0.6,两者存在正向关联。换句话说日最高气温可以解释Citi Bike租赁和骑行数量60%的变化原因。因此,我们通过这种关联分布对不同气温下的Citi Bike的租赁数量进行了预测。

以下是绘制散点图和进行回归分析的代码。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

#读取2015年纽约市的气象数据

weather=pd.DataFrame(pd.read_csv('823248.csv'))

#提取每日最高气温数据

group_weather_day=weather['TMAX']

#对2015年骑行时间按天汇总计算

cb_day=cb.resample('D',how=len)

#提起每日骑行数量

group_cb_day=cb_day['bikeid']

#对每日最高气温和骑行量数据进行标准化处理

fromsklearnimportpreprocessing

scaler=preprocessing.StandardScaler().fit(group_weather_day)

X_Standard=scaler.transform(group_weather_day)

scaler=preprocessing.StandardScaler().fit(group_cb_day)

Y_Standard=scaler.transform(group_cb_day)

#绘制最高气温和骑行数据散点图

plt.rc('font', family='STXihei', size=15)

plt.scatter(X_Standard,Y_Standard,60,color='#052B6C',marker='+',alpha=0.8,linewidth=1.5)

plt.xlabel('日最高气温')

plt.ylabel('Citi Bike租赁次数')

plt.title('最高气温与Citi Bike之间的关系')

plt.grid(color='#95a5a6',linestyle='--', linewidth=1,axis='both',alpha=0.4)

plt.show()

#设置每日最高气温为自变量X

X=np.array(weather[['TMAX']])

#设置每日骑行数量为因变量Y

Y=np.array(cb_day[['bikeid']])

#导入线性回归库

fromsklearnimportlinear_model

clf=linear_model.LinearRegression()

clf.fit (X,Y)

#计算相关度

clf.score(X,Y)

0.60841860048565455

#斜率

clf.coef_

array([[536.64465091]])

#截距

clf.intercept_

array([-7282.61437278])

回归方程:

2016102219

1

2

3

4

5

6

7

#分布对19,39和97华氏度的Citi Bike租赁量进行预测

clf.predict(19)

array([[2913.63399443]])

clf.predict(39)

array([[13646.52701255]])

clf.predict(97)

array([[44771.9167651]])

骑行速度与年龄是否存在关联

2016102220

通过前面的计算我们已经知道了每次骑行用户的年龄和骑行速度信息,那么这两者之间是否存在关联呢换句话说是否随着年龄的增长骑行速度会逐渐减慢呢我们通过简单的一元回归来分析下两者间的联系。这里我们只使用2015年5月的数据进行分析。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#计算并增加年龄字段

cb5['age']=2015-cb5['birth year']

#提取年龄和骑行速度字段

age_speed=cb5[['speed','age']]

#去除骑行速度为0的数据

age_speed=age_speed.dropna()

#年龄设置为自变量X

X=np.array(age_speed[['age']])

#速度设置为因变量Y

Y=np.array(age_speed[['speed']])

#导入线性回归库

fromsklearnimportlinear_model

#将数据导入模型

clf=linear_model.LinearRegression()

clf.fit (X,Y)

#斜率

clf.coef_

array([[-0.02899706]])

#截距

clf.intercept_

array([10.05513438])

#R方

clf.score(X,Y)

0.011272777068773165

从R方来看年龄与骑行速度间并没有关联,骑行速度并不会随着年龄的增长而增长。这里主要的原因我想有两个。第一Citi Bike的使用场所主要在城市里,并且多为短途。第二使用者除了城市居民上下班通勤外,还有一部分的游客,他们的目的是欣赏沿途美丽的风景因此骑行速度也会较慢。

1

2

3

4

5

6

7

#20岁的骑行速度预测为9.4公里

clf.predict(20)

array([[9.47519327]])

#50岁的骑行速度预测为8.6公里

clf.predict(50)

array([[8.60528161]])

哪些骑行线路最受欢迎

2016102221

在Citi Bike的官网上有一个频道叫Explore NYC,里面提供了最热门的骑行线路和沿途的著名景观。我们对5月的数据进行统计,找出最受欢迎的骑行开始地点。以及受欢迎的骑行线路。

Top10受欢迎的租赁点

对5月骑行数据进行统计,找出前10个最受欢迎的骑行开始地点及经纬度数据。将经纬度数据输入到plotly工具中,绘制出Citi Bike 2015年5月在纽约最受欢迎的前10个租赁地点。

2016102222

以下是前10个最受欢迎租赁点的统计代码及结果。

1

2

#使用数据透视找出前5个最受欢迎地点的经纬度数据

start_station=pd.pivot_table(cb5,index=["start station name","start station latitude","start station longitude"],values=['bikeid'],aggfunc=[len],fill_value=0,margins=True).head(10)

2016102223

热门骑行线路追踪

2016102224

继续前面的操作,在数据透视表的字段中增加结束地点和经纬度数据就可以看到一条完整的骑行线路数据,这里以1 Ave & E 15 St为骑行开始地点,使用plotly工具描绘出一条用户的骑行线路。上面的图中是从Google街景中截图的图片,也是骑行线路开始的地点。下面是plotly工具显示出的本次骑行开始和结束的位置。由于我们只有开始和结束两个经纬度数据,因此显示为一条直线。

2016102225

借助Google地图的骑行路线我们模拟出了用户这两点之间可能的骑行路线,这并非用户的真实骑行路线。但可以帮助我们更加详细的了解用户使用Citi Bike的情况。

20161022226

以下是通过数据透视获得骑行位置和经纬度的代码。

1

2

#获得骑行开始和结束地点及经纬度数据

end_station=pd.pivot_table(cb5,index=["start station name","start station latitude","start station longitude","end station latitude","end station longitude","end station name"],values=['bikeid'],aggfunc=[len],fill_value=0,margins=True).head(10)

20161022227

结束语

我们使用Python对纽约自行车共享系统Citi Bike 990万次骑行数据的简单分析,在惊叹于用户对自行车共享系统的热爱和使用频率的同时,也学习到很多用户骑行的信息。使用Citi Bike的用户以纽约市的中年男性为主,在每天的早晨的8点和傍晚6点是Citi Bike的使用高峰。由于Citi Bike对超时单独收取费用,用户的骑行时间多数在20分钟以内。用户对Citi Bike的使用受季节和气温的影响,相关度达到0.6,夏秋两季租赁量最大,冬季最低。用户的年龄与骑行速度关联并不紧密,平均骑行速度为6.3公里/小时。

以上是我们通过本次分析获得的结论,但对于Citi Bike和用户骑行的分析并没有结束。后续我们还会对在博客和公众号对Citi Bike的数据进行更多专项的分析和对比,如用户在每周的骑行趋势是什么样的工作日和休息日Citi Bike的使用率是否不同一辆自行车在一天中的路径是什么样的除了气温以外,还有哪些因素影响了用户对Citi Bike的使用敬请期待。

本文为专栏文章,来自:蓝鲸,内容观点不代表本站立场,如若转载请联系专栏作者,本文链接:https://www.afenxi.com/34868.html 。

更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: