机器学习-数据科学库day6

本文介绍了如何使用Python的pandas库对911紧急电话数据进行统计,包括不同类型的紧急情况次数及月份变化趋势。通过数据预处理、时间序列转换和重采样,展示了如何分析不同月份的电话次数,并进一步统计不同类型的紧急电话在各个月份的分布。此外,还提及了如何处理非标准时间字符串并进行降采样,以及如何绘制多个城市的PM2.5随时间变化的图表。
摘要由CSDN通过智能技术生成

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
#2015201725万条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()

结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值