Day6
现在我们有2015到2017年25万条911的紧急电话的数据,请统计出出这些数据中不同类型的紧急情况的次数
#coding=utf-8 import numpy as np import pandas as pd from matplotlib import pyplot as plt
file_path = "./911.csv"
df = pd.read_csv(file_path) # print(df.info()) #获取分类(EMS,Fire,Traffic..) # print(df["title"].str.split(":")) #temp_list:例[EMS, BACK PAINS/INJURY] temp_list = df["title"].str.split(":").tolist() cate_list = list(set(i[0] for i in temp_list)) #得到三个类型['EMS', 'Fire', 'Traffic'],还得统计个数 # print(cate_list)
#构造全为0的数组,行是df.shape[0],列是电话类型 zeros_df = pd.DataFrame(np.zeros((df.shape[0],len(cate_list))),columns=cate_list)
#赋值,遍历cate_list只有3个数据,遍历temp_list数据太多,太慢 for cate in cate_list: #contains()包含 #df["title"].str.contains(cate)是布尔索引 zeros_df[cate][df["title"].str.contains(cate)] = 1 print(zeros_df) #计算总数 sum_ret = zeros_df.sum(axis=0) print(sum_ret) |
结果:
Fire EMS Traffic
0 0.0 1.0 0.0
1 0.0 1.0 0.0
2 1.0 0.0 0.0
3 0.0 1.0 0.0
4 0.0 1.0 0.0
... ... ... ...
249732 0.0 1.0 0.0
249733 0.0 1.0 0.0
249734 0.0 1.0 0.0
249735 1.0 0.0 0.0
249736 0.0 0.0 1.0
[249737 rows x 3 columns]
Fire 37432.0
EMS 124844.0
Traffic 87465.0
dtype: float64
【方法二】
#coding=utf-8 #2015到2017年25万条911的紧急电话的数据 #请统计出出这些数据中不同类型的紧急情况的次数(方法2) import numpy as np import pandas as pd from matplotlib import pyplot as plt
file_path = "./911.csv"
df = pd.read_csv(file_path) # print(df.info()) #获取分类(EMS,Fire,Traffic..) # print(df["title"].str.split(":")) #temp_list:例[EMS, BACK PAINS/INJURY] temp_list = df["title"].str.split(":").tolist() #得到电话类型 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),columns=["cate"])
print(df.groupby(by="cate").count()["title"]) |
结果:
cate
EMS 124840
Fire 37432
Traffic 87465
Name: title, dtype: int64
注:
Series类型转换为列表是.tolist()
DataFrame是.to_list()
如果我们还想统计出不同月份不同类型紧急电话的次数的变化情况,应该怎么做呢?
为什么要学习pandas中的时间序列
不管在什么行业,时间序列都是一种非常重要的数据形式,很多统计数据以及数据的规律也都和时间序列有着非常重要的联系
而且在pandas中处理时间序列是非常简单的
生成一段时间范围
pd.date_range(start=None, end=None, periods=None, freq='D')
(periods指生成几个,D是指每隔一天,2D指每隔两天,M指每月)
start和end以及freq配合能够生成start和end范围内以频率freq的一组时间索引
start和periods以及freq配合能够生成从start开始的频率为freq的periods个时间索
【示例】
#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')
关于频率的更多缩写
在DataFrame中使用时间序列
index=pd.date_range("20170101",periods=10)
df = pd.DataFrame(np.random.rand(10),index=index)
回到最开始的911数据的案例中,我们可以使用pandas提供的方法把时间字符串转化为时间序列
df["timeStamp"] = pd.to_datetime(df["timeStamp"],format="")
format参数大部分情况下可以不用写,但是对于pandas无法格式化的时间字符串,我们可以使用该参数,比如包含中文
那么问题来了:
我们现在要统计每个月或者每个季度的次数怎么办呢?
pandas重采样
重采样:指的是将时间序列从一个频率转化为另一个频率进行处理的过程,将高频率数据转化为低频率数据为降采样,低频率转化为高频率为升采样
pandas提供了一个resample的方法来帮助我们实现
t.resample(‘M’).mean():按月计算平均值
t.resample(‘10D’).count():按10天来计算数量
统计出911数据中不同月份电话次数的变化情况
#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)
#统计出911数据中不同月份的电话次数 count_bymonth = df.resample("M").count()["title"] # print(count_bymonth)
#绘制折线图 _x = count_bymonth.index _y = count_bymonth.values
#把例如2015-12-10 00-00-00中的'00-00-00'去掉 _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
Freq: M, Name: title, dtype: int64统计出911数据中不同月份电话次数的变化情况
#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)
#统计出911数据中不同月份的电话次数 count_bymonth = df.resample("M").count()["title"] # print(count_bymonth)
#绘制折线图 _x = count_bymonth.index _y = count_bymonth.values
#把例如2015-12-10 00-00-00中的'00-00-00'去掉 _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
注:因为头尾两个月数据不完整,所以较低
统计出911数据中不同月份不同类型的电话的次数的变化情况
#coding=utf-8 import time #统计出911数据中不同月份不同类型的电话的次数的变化情况 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"])
#添加列,表示分类 #temp_list:例[EMS, BACK PAINS/INJURY] temp_list = df["title"].str.split(":").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() |
结果:
现在我们有北上广、深圳、和沈阳5个城市空气质量数据,请绘制出5个城市的PM2.5随时间的变化情况
观察这组数据中的时间结构,并不是字符串,这个时候我们应该怎么办?
PeriodIndex
之前所学习的DatetimeIndex可以理解为时间戳
那么现在我们要学习的PeriodIndex可以理解为时间段
(可以上传年,月,日,把分开的时间字符串通过periodIndex的方法转换为pandas的时间类型)
periods=pd.PeriodIndex(year=data["year"],month=data["month"],day=data["day"],hour=data["hour"],freq="H")
【示例】
#coding=utf-8 import pandas as pd
file_path="./PM2.5/BeijingPM20100101_20151231.csv"
df = pd.read_csv(file_path)
#PeriodIndex()方法 period = pd.PeriodIndex(year=df["year"],month=df["month"],day=df["day"],hour=df["hour"],freq="H") print(period) |
结果:
PeriodIndex(['2010-01-01 00:00', '2010-01-01 01:00', '2010-01-01 02:00',
'2010-01-01 03:00', '2010-01-01 04:00', '2010-01-01 05:00',
'2010-01-01 06:00', '2010-01-01 07:00', '2010-01-01 08:00',
'2010-01-01 09:00',
...
'2015-12-31 14:00', '2015-12-31 15:00', '2015-12-31 16:00',
'2015-12-31 17:00', '2015-12-31 18:00', '2015-12-31 19:00',
'2015-12-31 20:00', '2015-12-31 21:00', '2015-12-31 22:00',
'2015-12-31 23:00'],
dtype='period[H]', length=52584, freq='H')
那么如果给这个时间段降采样呢?
data = df.set_index(periods).resample("10D").mean()
【操作】
#coding=utf-8 #我们有北上广、深圳、和沈阳5个城市空气质量数据 #请绘制出5个城市的PM2.5随时间的变化情况 import time
import pandas as pd from matplotlib import pyplot as plt
file_path="./PM2.5/BeijingPM20100101_20151231.csv"
df = pd.read_csv(file_path)
#PeriodIndex()方法,把分开的时间字符串转换为pandas的时间类型 period = pd.PeriodIndex(year=df["year"],month=df["month"],day=df["day"],hour=df["hour"],freq="H") df["datetime"] = period print(df.head(10))
#把datetime 设置为索引 df.set_index("datetime",inplace=True)
#数据太多,进行降采样 df = df.resample("7D").mean() #313条数据
#处理缺失数据(PM_US Post,即美国统计的pm2.5数据),删除缺失(Nan)数据 #删除PM_US Post这列中的nan data = df["PM_US Post"].dropna() #中国统计的数据 data_china = df["PM_Dongsi"].dropna()
#画图(中国) _x_china = data_china.index _x_china = [i.strftime("%Y%m%d") for i in _x_china] _y_china = data_china.values # _y_china = [i.strftime("%Y%m%d") for i in _y_china]
#画图(美国) _x = data.index #格式化时间 _x = [i.strftime("%Y%m%d") for i in _x] _y = data.values
plt.figure(figsize=(20,8),dpi=80)
plt.plot(range(len(_x)),_y,label="US_POST") plt.plot(range(len(_x_china)),_y_china,label="CN_POST")
plt.xticks(range(0,len(_x),10),list(_x)[::10],rotation=45) plt.legend(loc="best") plt.show() |
结果: