如果我们还想统计出不同月份不同类型紧急电话的次数的变化情况,应该怎么做呢?
这里需要处理时间,而不同数据的时间有不同的表示方式,我们需要统一时间格式,所以学习如何处理时间序列,但是和我大三学习的时间序列分析又不太一样。
而且在pandas里面学习时间学列非常容易。
一、pd.data_range(start=,end=,periods=,freq='D' )时间索引
(periods指生成几个,D是指每隔一天,2D指每隔两天,M指每月)
【示例】
#coding = utf-8
import pandas as pd
x = pd.date_range(start="20171230",end="20180110",freq="D")
print(x)
y = pd.date_range(start="20171230",end="20180110",freq="2D")
print(y)
z = pd.date_range(start="20171230",periods=10,freq="M")
print(z)
DatetimeIndex(['2017-12-30', '2017-12-31', '2018-01-01', '2018-01-02',
'2018-01-03', '2018-01-04', '2018-01-05', '2018-01-06',
'2018-01-07', '2018-01-08', '2018-01-09', '2018-01-10'],
dtype='datetime64[ns]', freq='D')
DatetimeIndex(['2017-12-30', '2018-01-01', '2018-01-03', '2018-01-05',
'2018-01-07', '2018-01-09'],
dtype='datetime64[ns]', freq='2D')
DatetimeIndex(['2017-12-31', '2018-01-31', '2018-02-28', '2018-03-31',
'2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31',
'2018-08-31', '2018-09-30'],
dtype='datetime64[ns]', freq='M')
频率又有不同的缩写:
D | 每日历日 |
B | 每工作日 |
H、T、S | 每小时、分钟、秒 |
M | 每个月最后一个日历日(30,28,31) |
MS | 每个月第一个日历日 |
BM | 每个月最后一个工作日 |
二、pd.to_datatime(df[""],format=%m)将时间字符串转换为pandas里面事件类型,再进行重采样操作.
重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样。
例如:我们知道2017-12-10的10时间段的打电话次数,精确到秒;但是我们想知道这一天的打电话次数,精确到天。这个就是降采样。
pandas提供了一个resample()的方法来帮助我们实现
接下来 完成两个练习
1、统计出911数据中不同月份电话次数的变化情况(按秒计算的变成按月的再count一下,再画个折线图)
#coding=utf-8
import time
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
file_path = "./911.csv"
df = pd.read_csv(file_path)
#把时间字符串转换为pandas的时间类型
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
#set_index可以指定数据中的某一列,将其作为该数据的新索引
df.set_index("timeStamp",inplace=True)##inplace=TRUE说明原地不变
#统计出911数据中不同月份的电话次数
count_bymonth = df.resample("M").count()["title"]###只取title那一列就好了
# print(count_bymonth)
#绘制折线图
_x = count_bymonth.index
_y = count_bymonth.values
#把例如2015-12-10 00-00-00中的'00-00-00'去掉,strftime(%Y%m%d)年月日
_x = [i.strftime("%Y%m%d") for i in _x]
plt.figure(figsize=(20,8),dpi=80)
plt.plot(range(len(_x)),_y)
#x刻度
plt.xticks(range(len(_x)),_x,rotation=45)
plt.show()
结果:
timeStamp
2015-12-31 7916
2016-01-31 13096
2016-02-29 11396
2016-03-31 11059
2016-04-30 11287
2016-05-31 11374
2016-06-30 11732
2016-07-31 12088
2016-08-31 11904
2016-09-30 11669
2016-10-31 12502
2016-11-30 12091
2016-12-31 12162
2017-01-31 11605
2017-02-28 10267
2017-03-31 11684
2017-04-30 11056
2017-05-31 11719
2017-06-30 12333
2017-07-31 11768
2017-08-31 11753
2017-09-30 7276
接下来出图,我以为pycharm里面保存图片很麻烦呢,结果我发现就是复制粘贴
注:结果和图片中都显示月头和月尾数据较少,因为数据不完整
2.统计出911数据中不同月份不同类型的电话的次数的变化情况
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
#把时间字符串转换为pandas的时间类型设置为索引
file_path = "./911.csv"
df = pd.read_csv(file_path)
df["timeStamp"] = pd.to_datetime(df["timeStamp"])
#添加列,表示分类
#temp_list:例[EMS, BACK PAINS/INJURY]
temp_list = df["title"].str.split(":").tolist()##tolist转换成列表
#cate_list得到三个类型['EMS', 'Fire', 'Traffic']
cate_list = [i[0] for i in temp_list]
#df多创建一列cate,可以groupby
df["cate"] = pd.DataFrame(np.array(cate_list).reshape((df.shape[0],1)))
#注:此处需把df.set_index("timeStamp",inplace=True)放到创建cate列之后
#如果放在前面,则df.shape[0]会发生改变
#将原本的列'timeStamp'设置为新的索引
df.set_index("timeStamp",inplace=True)
plt.figure(figsize=(20,8),dpi=80)
#按类型分组(groupby后为数据为元组类型,有两个数据)
for group_name,group_data in df.groupby(by="cate"):
#对不同的分类(3个类型)都进行绘图(group_name是类型,group_data是数据)
#按月统计
count_by_month = group_data.resample("M").count()["title" ]
#绘图
_x = count_by_month.index
_y = count_by_month.values
#格式化时间
_x = [i.strftime("%Y%m%d") for i in _x]
plt.plot(range(len(_x)),_y,label = group_name)
plt.xticks(range(len(_x)),_x,rotation=45)
plt.legend(loc="best") #loc是图例位置
plt.show()