import pandas as pd
data = pd.read_csv(r'data-sample/TaxiData-Sample',header=None) #读取数据
data.columns=['VehicleNum','Stime','lng','lat','openstatus','speed'] #给数据赋上列名
data
VehicleNum | Stime | lng | lat | openstatus | speed | |
---|---|---|---|---|---|---|
0 | 22271 | 22:54:04 | 114.167000 | 22.718399 | 0 | 0 |
1 | 22271 | 18:26:26 | 114.190598 | 22.647800 | 0 | 4 |
2 | 22271 | 18:35:18 | 114.201401 | 22.649700 | 0 | 0 |
3 | 22271 | 16:02:46 | 114.233498 | 22.725901 | 0 | 24 |
4 | 22271 | 21:41:17 | 114.233597 | 22.720900 | 0 | 19 |
... | ... | ... | ... | ... | ... | ... |
1601302 | 23873 | 20:20:03 | 114.160149 | 22.606934 | 0 | 0 |
1601303 | 23873 | 20:15:13 | 114.164551 | 22.605118 | 1 | 48 |
1601304 | 23873 | 20:16:23 | 114.168015 | 22.606083 | 0 | 0 |
1601305 | 23873 | 20:16:43 | 114.168015 | 22.606083 | 0 | 0 |
1601306 | 23873 | 20:26:39 | 114.170647 | 22.604383 | 0 | 0 |
1601307 rows × 6 columns
# 第一节 提取Stime中的小时 赋给新的一列hour 三种方法
#方法一: pandas中 字符串的slice
data['Stime'].iloc[0] # 提取Stime的第一行数据 看是什么类型的 结果显示是字符串
'22:54:04'
data['Stime'].str.slice(0,2) #提取str的前两位就是小时
0 22
1 18
2 18
3 16
4 21
..
1601302 20
1601303 20
1601304 20
1601305 20
1601306 20
Name: Stime, Length: 1601307, dtype: object
# 自行百度pandas中str内置的方法
data['hour']=data['Stime'].str.slice(0,2) #把提取出来的结果赋到新的一列
data
VehicleNum | Stime | lng | lat | openstatus | speed | hour | |
---|---|---|---|---|---|---|---|
0 | 22271 | 22:54:04 | 114.167000 | 22.718399 | 0 | 0 | 22 |
1 | 22271 | 18:26:26 | 114.190598 | 22.647800 | 0 | 4 | 18 |
2 | 22271 | 18:35:18 | 114.201401 | 22.649700 | 0 | 0 | 18 |
3 | 22271 | 16:02:46 | 114.233498 | 22.725901 | 0 | 24 | 16 |
4 | 22271 | 21:41:17 | 114.233597 | 22.720900 | 0 | 19 | 21 |
... | ... | ... | ... | ... | ... | ... | ... |
1601302 | 23873 | 20:20:03 | 114.160149 | 22.606934 | 0 | 0 | 20 |
1601303 | 23873 | 20:15:13 | 114.164551 | 22.605118 | 1 | 48 | 20 |
1601304 | 23873 | 20:16:23 | 114.168015 | 22.606083 | 0 | 0 | 20 |
1601305 | 23873 | 20:16:43 | 114.168015 | 22.606083 | 0 | 0 | 20 |
1601306 | 23873 | 20:26:39 | 114.170647 | 22.604383 | 0 | 0 | 20 |
1601307 rows × 7 columns
# 方法二: apply方法
#先提取第一行 定义函数 提取这一行的前两个字符
r=data['Stime'].iloc[0]
def f(r):
return r[:2]
#应用apply到data['Stime']的每一行
data['Stime'].apply(f)
0 22
1 18
2 18
3 16
4 21
..
1601302 20
1601303 20
1601304 20
1601305 20
1601306 20
Name: Stime, Length: 1601307, dtype: object
#方法二改进写法: Lambda DataFrame
f1=lambda r:r[0:2] #注意格式
f1(r)
'22'
data['hour']=data['Stime'].apply(lambda r:r[0:2])# 优美简洁 三种方法中最快
data
VehicleNum | Stime | lng | lat | openstatus | speed | hour | |
---|---|---|---|---|---|---|---|
0 | 22271 | 22:54:04 | 114.167000 | 22.718399 | 0 | 0 | 22 |
1 | 22271 | 18:26:26 | 114.190598 | 22.647800 | 0 | 4 | 18 |
2 | 22271 | 18:35:18 | 114.201401 | 22.649700 | 0 | 0 | 18 |
3 | 22271 | 16:02:46 | 114.233498 | 22.725901 | 0 | 24 | 16 |
4 | 22271 | 21:41:17 | 114.233597 | 22.720900 | 0 | 19 | 21 |
... | ... | ... | ... | ... | ... | ... | ... |
1601302 | 23873 | 20:20:03 | 114.160149 | 22.606934 | 0 | 0 | 20 |
1601303 | 23873 | 20:15:13 | 114.164551 | 22.605118 | 1 | 48 | 20 |
1601304 | 23873 | 20:16:23 | 114.168015 | 22.606083 | 0 | 0 | 20 |
1601305 | 23873 | 20:16:43 | 114.168015 | 22.606083 | 0 | 0 | 20 |
1601306 | 23873 | 20:26:39 | 114.170647 | 22.604383 | 0 | 0 | 20 |
1601307 rows × 7 columns
#apply 方法改进 之前是用在data['Stime']是series 一列里面 下面用在dataframe里面 dataframe是好多列
#对比
r=data.iloc[0]
r #Dataframe类型
VehicleNum 22271
Stime 22:54:04
lng 114.167
lat 22.7184
openstatus 0
speed 0
hour 22
Name: 0, dtype: object
r1=data['Stime'].iloc[0]
r1 #series类型
'22:54:04'
data.apply(lambda r:r['Stime'][0:2],axis=1) #注意格式 ['Stime']是在冒号后面不是前面 运行速度比series慢 axis=1从列找 =0从行找
0 22
1 18
2 18
3 16
4 21
..
1601302 20
1601303 20
1601304 20
1601305 20
1601306 20
Length: 1601307, dtype: object
#方法三: 用pandas中内置的时间转换的方法 时间更慢 一百多万条数据要转换格式
tmp=pd.to_datetime(data['Stime'])
tmp
0 2021-01-21 22:54:04
1 2021-01-21 18:26:26
2 2021-01-21 18:35:18
3 2021-01-21 16:02:46
4 2021-01-21 21:41:17
...
1601302 2021-01-21 20:20:03
1601303 2021-01-21 20:15:13
1601304 2021-01-21 20:16:23
1601305 2021-01-21 20:16:43
1601306 2021-01-21 20:26:39
Name: Stime, Length: 1601307, dtype: datetime64[ns]
tmp.apply(lambda r:r.hour) # r在前面定义了 是tmp.apply 不是 data.apply
0 22
1 18
2 18
3 16
4 21
..
1601302 20
1601303 20
1601304 20
1601305 20
1601306 20
Name: Stime, Length: 1601307, dtype: int64
data
VehicleNum | Stime | lng | lat | openstatus | speed | hour | |
---|---|---|---|---|---|---|---|
0 | 22271 | 22:54:04 | 114.167000 | 22.718399 | 0 | 0 | 22 |
1 | 22271 | 18:26:26 | 114.190598 | 22.647800 | 0 | 4 | 18 |
2 | 22271 | 18:35:18 | 114.201401 | 22.649700 | 0 | 0 | 18 |
3 | 22271 | 16:02:46 | 114.233498 | 22.725901 | 0 | 24 | 16 |
4 | 22271 | 21:41:17 | 114.233597 | 22.720900 | 0 | 19 | 21 |
... | ... | ... | ... | ... | ... | ... | ... |
1601302 | 23873 | 20:20:03 | 114.160149 | 22.606934 | 0 | 0 | 20 |
1601303 | 23873 | 20:15:13 | 114.164551 | 22.605118 | 1 | 48 | 20 |
1601304 | 23873 | 20:16:23 | 114.168015 | 22.606083 | 0 | 0 | 20 |
1601305 | 23873 | 20:16:43 | 114.168015 | 22.606083 | 0 | 0 | 20 |
1601306 | 23873 | 20:26:39 | 114.170647 | 22.604383 | 0 | 0 | 20 |
1601307 rows × 7 columns
#第二节 通过hour这一列对数据进行分组 集计 画图
data.groupby('hour') # 结果是一个对象Object 里面包括 各种集计的函数 count sum
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001B2E417FD00>
data.groupby('hour').count()
VehicleNum | Stime | lng | lat | openstatus | speed | |
---|---|---|---|---|---|---|
hour | ||||||
00 | 68745 | 68745 | 68745 | 68745 | 68745 | 68745 |
01 | 63142 | 63142 | 63142 | 63142 | 63142 | 63142 |
02 | 60680 | 60680 | 60680 | 60680 | 60680 | 60680 |
03 | 57494 | 57494 | 57494 | 57494 | 57494 | 57494 |
04 | 57060 | 57060 | 57060 | 57060 | 57060 | 57060 |
05 | 59636 | 59636 | 59636 | 59636 | 59636 | 59636 |
06 | 59742 | 59742 | 59742 | 59742 | 59742 | 59742 |
07 | 63780 | 63780 | 63780 | 63780 | 63780 | 63780 |
08 | 68224 | 68224 | 68224 | 68224 | 68224 | 68224 |
09 | 64026 | 64026 | 64026 | 64026 | 64026 | 64026 |
10 | 69309 | 69309 | 69309 | 69309 | 69309 | 69309 |
11 | 71286 | 71286 | 71286 | 71286 | 71286 | 71286 |
12 | 65876 | 65876 | 65876 | 65876 | 65876 | 65876 |
13 | 69212 | 69212 | 69212 | 69212 | 69212 | 69212 |
14 | 71510 | 71510 | 71510 | 71510 | 71510 | 71510 |
15 | 70241 | 70241 | 70241 | 70241 | 70241 | 70241 |
16 | 71798 | 71798 | 71798 | 71798 | 71798 | 71798 |
17 | 70333 | 70333 | 70333 | 70333 | 70333 | 70333 |
18 | 63514 | 63514 | 63514 | 63514 | 63514 | 63514 |
19 | 74179 | 74179 | 74179 | 74179 | 74179 | 74179 |
20 | 74938 | 74938 | 74938 | 74938 | 74938 | 74938 |
21 | 70069 | 70069 | 70069 | 70069 | 70069 | 70069 |
22 | 71503 | 71503 | 71503 | 71503 | 71503 | 71503 |
23 | 65010 | 65010 | 65010 | 65010 | 65010 | 65010 |
data.groupby('hour')['VehicleNum'].count() # 注意格式 ('hour')['VehicleNum']中间没有符号
hour
00 68745
01 63142
02 60680
03 57494
04 57060
05 59636
06 59742
07 63780
08 68224
09 64026
10 69309
11 71286
12 65876
13 69212
14 71510
15 70241
16 71798
17 70333
18 63514
19 74179
20 74938
21 70069
22 71503
23 65010
Name: VehicleNum, dtype: int64
data.groupby('hour')['VehicleNum'].count().reset_index() # 规范化 新产生index列 不是使用hour作为index列
hour | VehicleNum | |
---|---|---|
0 | 00 | 68745 |
1 | 01 | 63142 |
2 | 02 | 60680 |
3 | 03 | 57494 |
4 | 04 | 57060 |
5 | 05 | 59636 |
6 | 06 | 59742 |
7 | 07 | 63780 |
8 | 08 | 68224 |
9 | 09 | 64026 |
10 | 10 | 69309 |
11 | 11 | 71286 |
12 | 12 | 65876 |
13 | 13 | 69212 |
14 | 14 | 71510 |
15 | 15 | 70241 |
16 | 16 | 71798 |
17 | 17 | 70333 |
18 | 18 | 63514 |
19 | 19 | 74179 |
20 | 20 | 74938 |
21 | 21 | 70069 |
22 | 22 | 71503 |
23 | 23 | 65010 |
hourcount=data.groupby('hour')['VehicleNum'].count().reset_index()
#画图
#一般,用matplotlib绘图的代码由3部分组成
#第一部分:创建图
import matplotlib.pyplot as plt
#创建一个图用plt.figure
#其中fig你可以想象是整张图,ax是图上的其中一个小画板(一个大图可以有多个小画板)
#而plt则是我们的画笔
fig = plt.figure(1,(8,4))
ax = plt.subplot(111)
#告诉画笔,我们要在ax上画图
plt.sca(ax)
#第二部分:绘制
#用plt.plot画折线
plt.plot(hourcount['hour'],hourcount['VehicleNum']) # plot(x,y) x,y为坐标参数
#第三部分:调整
plt.title('Hourly data Volume')
plt.show()
# 画图就是这个流程 必要时只需修改参数
fig = plt.figure(1,(8,4),dpi=250) # 创建一张画板 长为8 宽为4 dpi是分辨率 学术作图一般300以上 250够用
ax = plt.subplot(111) # 里面一行一列第一张纸就是ax
plt.sca(ax)
plt.plot(hourcount['hour'],hourcount['VehicleNum'],'k-',hourcount['hour'],hourcount['VehicleNum'],'k.') # 前面是画条线 k-是黑色实线 k.就是在每个节点打一个实点上去
plt.bar(hourcount['hour'],hourcount['VehicleNum'],width =0.5) # 加上条形图
plt.ylim(0,80000) # 设置y轴的取值范围 上面y轴不是从0开始 会有一些误导
plt.title('Hourly data Volume')
plt.savefig(fname='test.svg',format='svg',bbox_inches='tight')# svg是矢量图 无限放大不影响分辨率 bbox_inches='tight'去除边框 可以直接粘贴到论文里
plt.show() # 会清空画板