系列文章目录


Python数据分析入门笔记1——学习前的准备

Python数据分析入门笔记2——pandas数据读取

Python数据分析入门笔记3——数据预处理之缺失值

Python数据分析入门笔记4——数据预处理之重复值

Python数据分析入门笔记5——数据预处理之异常值

Python数据分析入门笔记6——数据清理案例练习

Python数据分析入门笔记7——数据集成、变换与规约


Python数据分析入门笔记

  • 系列文章目录
  • 前言
  • 一、datetime对象
  • 1. 快速上手,自己创建
  • 2. 将pandas中的数据转换成datetime对象——to_datetime()
  • 3. 提取日期的各个部分
  • 4. 日期运算和Timedelta
  • 5. 日期范围的处理——date_range函数
  • 二、案例——丹佛市犯罪数据
  • 1. 读取文件,设置索引。——read_csv()和set_index()
  • 2. 查看指定日期的记录——loc
  • 3. 查看指定日期范围的记录——loc
  • 4. 查看指定时间范围的报警记录——between_time()
  • 5. 查看发生在某个时刻的犯罪记录——at_time()
  • 6. 按周统计——resample('W')
  • 7. 分析季度数据——resample('Q')
  • 8. 按是否工作日分析
  • 总结



前言

文中用到的练习资源文件,可直接点击下载:

  1. 埃博拉疫情数据分析
  2. 丹佛市犯罪信息

一、datetime对象

关于时间模块更多内容,可查看此文:Python模块——datatime

1. 快速上手,自己创建

  • 获取当前时间,计算距离WHO宣布新冠疫情大流行多久
import pandas as pd
from datetime import datetime
# 获取当前时间
now = datetime.now()
t2 = datetime(2020,3,11)
diff = now - t2
print(diff)

python csv 日期格式 插入数据表 python处理日期数据_数据挖掘


哦,原来已经两年多了,希望疫情快些结束吧!!!!!!

2. 将pandas中的数据转换成datetime对象——to_datetime()

  • 可以使用to_datetime函数把数据转换成datetime类型。
    示例:读取ebola数据文件,发现日期列数据格式无法识别,因此需要转换为datetime类型后再新开一列。
# 加载数据 并把Date列转换为datetime对象
ebola = pd.read_csv('data/country_timeseries.csv')
# 获取左上角数据,取前五行前五列
ebola.iloc[:5,:5]
#用ebola.info()查看发现文件中的日期类型并不标准,只能识别为object

python csv 日期格式 插入数据表 python处理日期数据_python_02

# 因此需要调用to_datetime方法,将这一列转换后放入新的列中
ebola['date_dt'] = pd.to_datetime(ebola['Date'])
# parse_dates属性,数值为0说明0号列中是时间数据
ebola = pd.read_csv('data/country_timeseries.csv',parse_dates=[0])
# 最后再取前五行前五列观察一下数据的变化
ebola.iloc[:5,:5]

python csv 日期格式 插入数据表 python处理日期数据_数据分析_03

3. 提取日期的各个部分

  • 可以通过Timestamp类型来获取年、月、日等部分的信息

示例:将Ebola数据中Date列日期信息,拆分为year、month和day三列。

# 新建year列,用来存储拆分出来的年份信息
ebola['year'] = ebola['Date'].dt.year
# 同时创建两列,分别存储月份和天信息
ebola['month'],ebola['day']  = (ebola['Date'].dt.month,ebola['Date'].dt.day)
# 查看指定四列数据中的前五条
ebola[['Date','year','month','day']].head()

python csv 日期格式 插入数据表 python处理日期数据_数据_04

4. 日期运算和Timedelta

  • 可以结合Python自带函数,获取最大时间和最小时间

示例:Ebola数据集中的Day列表示一个国家爆发Ebola疫情的天数。这一列数据可以通过日期运算重建该列
疫情爆发的第一天(数据集中最早的一天)是2014-03-22。计算疫情爆发的天数时,只需要用每个日期减去这个日期即可。

# 获取疫情爆发的第一天
ebola['Date'].min()

能看到,Ebola疫情最早爆发时间是:

python csv 日期格式 插入数据表 python处理日期数据_数据挖掘_05


然后计算出疫情爆发天数,写入新建的“outbreak_d”列中,这个计算出的数据类型就是timedelta

ebola['outbreak_d'] = ebola['Date']-ebola['Date'].min()
ebola[['Date','Day','outbreak_d']].head()

5. 日期范围的处理——date_range函数

包含日期的数据集中,并非每一个都包含固定频率。比如在Ebola数据集中,日期并没有规律。

# 查看前五行和后五行数据
ebola.iloc[:,:5]

python csv 日期格式 插入数据表 python处理日期数据_数据分析_06

从上面的数据中可以看到,缺少2015年1月1日,2014年3月23日,如果想让日期连续,可以创建一个日期范围来为数据集重建索引。

  • 可以使用date_range函数来创建连续的日期范围

    date_range函数格式(start、end和periods三个参数至少指定两个):

date_range(start=None, end=None, periods=None, freq=None, tz=None, normalize=False, name=None, closed=None, **kwargs)

参数说明:

参数名

说明

start

指定生成时间序列的开始时间

end

指定生成时间序列的结束时间

periods

指定生成时间序列的数量

freq

生成频率,默认为‘D’,即时间跨度为一天。W为每周,M为每月,Q为每季度,B为工作日…

小例子:

python csv 日期格式 插入数据表 python处理日期数据_数据_07

二、案例——丹佛市犯罪数据

任务说明:

  1. 读取csv文件,设置报警时间为索引。
  2. 查看2016年5月12号的报警记录。
  3. 查看2015年3月4日到2016年1月1日的犯罪记录。
  4. 查看凌晨两点到五点的报警记录
  5. 查看发生在5点47分的犯罪记录
  6. 计算每周的犯罪数量
  7. 分析每季度的犯罪和交通事故数据

1. 读取文件,设置索引。——read_csv()和set_index()

import pandas as pd
# 读取文件,用parse_dates将时间数据转换为日期格式
crime=pd.read_csv('data/crime.csv',parse_dates=['REPORTED_DATE'])
# 将报警时间这一列设置为索引
crime=crime.set_index('REPORTED_DATE')

(1)验证步骤:

首先需要执行crime.info(),检测文档中的REPORTED_DATE列是不是正确的datetime格式

python csv 日期格式 插入数据表 python处理日期数据_数据_08


然后需要执行crime.head(),看前五行的数据情况,检验索引是否设置成功,如果设置成功,索引列会放在最左边,数据如下图:

python csv 日期格式 插入数据表 python处理日期数据_Python_09

(2)特别注意:
最开始设置索引的语句中,设置完索引的对象我没有更新到crime中,写成了
crime.set_index(‘REPORTED_DATE’)
这样做的结果就是,索引一直不生效,加上inplace=True就可以了

# crime=crime.set_index('REPORTED_DATE')这一行也可以写成下述格式
crime.set_index('REPORTED_DATE',inplace=True)

(3)不懂就问:
这里为什么必须设置inplace?原有的列不能直接设置为索引吗?

2. 查看指定日期的记录——loc

  • 查看2016年5月12日的犯罪记录。
    注意,遇到这种查看指定日期或指定时间范围的问题,最好提前排序,后续直接对有序对象进行操作。
# 为了方便后续操作,这里将时间索引排序
crime_sort=crime.sort_index()
# 后续都对crime_sort对象进行操作
crime_sort.loc['2016-05-12']

正常情况下的运行结果如图:

python csv 日期格式 插入数据表 python处理日期数据_python_10

特别注意:一定要保证上一步中的索引设置成功,我一开始由于索引没设置上,所以一直报错,而且KeyError中并没有明确指示,费老劲了。报错截图如下:

python csv 日期格式 插入数据表 python处理日期数据_数据分析_11


python csv 日期格式 插入数据表 python处理日期数据_数据挖掘_12

3. 查看指定日期范围的记录——loc

  • 查看2015-3-4到2016-1-1时间段的犯罪记录。
  1. 若使用的是未经排序的crime,就需要在最后面加上sort_index()排一下序
crime.loc['2015-3-4':'2016-1-1'].sort_index()
  1. 若使用的是排序过的crime_sort,则可直接查看
crime_sort.loc['2015-3-4':'2016-1-1']

正常运行结果如图:

python csv 日期格式 插入数据表 python处理日期数据_python_13

特别注意:由于我一开始索引没设置好,默认是按数字递增的索引,因此用loc拿到的数据也是错误的,错误截图如下:

python csv 日期格式 插入数据表 python处理日期数据_数据_14

4. 查看指定时间范围的报警记录——between_time()

  • 查询凌晨两点到五点的报警记录
crime.between_time('2:00', '5:00', include_end=False)

运行结果如下:

python csv 日期格式 插入数据表 python处理日期数据_数据分析_15

5. 查看发生在某个时刻的犯罪记录——at_time()

  • 查看发生在5点47分的犯罪记录
crime.at_time('5:47')

运行结果如下:

python csv 日期格式 插入数据表 python处理日期数据_数据挖掘_16

6. 按周统计——resample(‘W’)

为了统计每周的犯罪数量,需要按周分组。
这里用到了resample重采样,降低采样频率。
(1)调用resample()方法,设置为按周采样

crime_sort.resample('W')

分组结束后,需要用size查看一下分组大小

# size查看分组大小,即每周犯罪数量
weekly_crimes=crime_sort.resample('W').size()
weekly_crimes

python csv 日期格式 插入数据表 python处理日期数据_python_17


然后可以检验一下分组结果,如len(crime_sort.loc[‘2012-1-9’:‘2012-1-15’])

执行后也输出1071,说明数据无误

(2)将按周分组的结果,做可视化处理

from matplotlib import pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
weekly_crimes.plot(figsize=(16,4),title="丹佛犯罪情况")

python csv 日期格式 插入数据表 python处理日期数据_python_18


特别注意:

若标题上的中文显示为小方框,说明中文无法识别。

亲测事先引入matplotlib库设置中文后即可解决。

7. 分析季度数据——resample(‘Q’)

  • 分析每季度的犯罪和交通事故数据。若犯罪用‘IS_CRIME’列表示,交通事故用’IS_TRAFFIC’列表示。

(1)用resample进行重采样,拿到季度数据。

crime_quarterly=crime_sort.resample('Q')['IS_CRIME','IS_TRAFFIC'].sum()
crime_quarterly

运行结果如下:

python csv 日期格式 插入数据表 python处理日期数据_数据_19


(2)所有日期都是该季度的最后一天,因此要使用QS生成每季度的第一天

crime_sort.resample('QS')['IS_CRIME', 'IS_TRAFFIC'].sum().head()

python csv 日期格式 插入数据表 python处理日期数据_数据分析_20

(3)【这里看不懂,**代表指针吗?望大神指路】作图

plot_kwargs = dict(figsize=(16,4), color=['black', 'blue'], title='丹佛犯罪和交通事故数据')
crime_quarterly.plot(**plot_kwargs)

8. 按是否工作日分析

  • 分析工作日的犯罪情况:可以通过Timestamp的dt属性得到周几,然后统计
crime = pd.read_csv('data/crime.csv', parse_dates=['REPORTED_DATE'])
wd_counts = crime['REPORTED_DATE'].dt.weekday.value_counts()
wd_counts

python csv 日期格式 插入数据表 python处理日期数据_Python_21


总结

终于勉强把这个内容做了一遍。。。
关于最后那个案例,推荐这个文章:
《Pandas Cookbook》第10章 时间序列分析