10 datetime 数据类型¶
学习目标¶
- 应用Pandas来处理日期时间类型数据
1 datetime介绍¶
1.1 Python的datetime对象¶
- Python内置了datetime对象,可以在datetime库中找到
from datetime import datetime
t1 = datetime.now()
t1
t2 = datetime(2021,1,1)
t2
1.2 将pandas中的数据转换成datetime¶
- 可以使用to_datetime函数把数据转换成datetime类型
#加载数据 并把Date列转换为datetime对象
ebola = pd.read_csv('data/country_timeseries.csv').iloc[:5,:5]
- 从数据中看出 Date列是日期,但通过info查看加载后数据为object类型
ebola.info()
- 可以通过to_datetime方法把Date列转换为datetime
ebola['Date'] = pd.to_datetime(ebola['Date'])
ebola.info()
- 也可以在加载的时候,通过parse_dates参数指定日期时间列
ebola = pd.read_csv('data/country_timeseries.csv',parse_dates=[0]).iloc[:5,:5]
ebola.info()
1.3 提取日期的各个部分¶
- 获取了一个datetime对象,就可以提取日期的各个部分了
d = pd.to_datetime('2020-06-20')
d # Timestamp('2020-06-20 00:00:00')
- 可以看到得到的数据是Timestamp类型,通过Timestamp可以获取年,月,日等部分
d.year
d.month
d.day
- 通过ebola数据集的Date列,创建新列year
ebola['year'] = ebola['Date'].dt.year
ebola['year']
显示结果:
0 2015 1 2015 2 2015 3 2015 4 2014 ... 117 2014 118 2014 119 2014 120 2014 121 2014 Name: year, Length: 122, dtype: int64
1.4 日期范围 date_range¶
- 可以使用date_range函数来创建连续的日期范围
head_range = pd.date_range(start='2014-12-31',end='2015-01-05')
head_range
显示结果:
DatetimeIndex(['2014-12-31', '2015-01-01', '2015-01-02', '2015-01-03', '2015-01-04', '2015-01-05'], dtype='datetime64[ns]', freq='D')
- 使用date_range函数创建日期序列时,可以传入一个参数freq,默认情况下freq取值为D,表示日期范围内的值是逐日递增的。
# 2020年1月1日这周所有的工作日
pd.date_range('2020-01-01','2020-01-07',freq='B')
显示结果:
DatetimeIndex(['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-06', '2020-01-07'], dtype='datetime64[ns]', freq='B')
- 从结果中看到生成的日期中缺少1月4日,1月5日,为休息日
Alias | Description |
---|---|
B | 工作日 |
C | 自定义工作日 |
D | 日历日 |
W | 每周 |
M | 月末 |
SM | 月中和月末(每月第15天和月末) |
BM | 月末工作日 |
CBM | 自定义月末工作日 |
MS | 月初 |
SMS | 月初和月中(每月第1天和第15天) |
BMS | 月初工作日 |
CBMS | 自定义月初工作日 |
Q | 季度末 |
BQ | 季度末工作日 |
QS | 季度初 |
BQS | 季度初工作日 |
A, Y | 年末 |
BA, BY | 年末工作日 |
AS, YS | 年初 |
BAS, BYS | 年初工作日 |
BH | 工作时间 |
H | 小时 |
T, min | 分钟 |
S | 秒 |
L, ms | 毫秒 |
U, us | microseconds |
N | 纳秒 |
- 在freq传入参数的基础上,可以做一些调整
# 隔一个工作日取一个工作日
pd.date_range('2020-01-01','2020-01-07',freq='2B')
显示结果:
DatetimeIndex(['2020-01-01', '2020-01-03', '2020-01-07'], dtype='datetime64[ns]', freq='2B')
- freq传入的参数可以传入多个
#2020年每个月的第一个星期四
# 星期几缩写:MON/TUE/WED/THU/FRI/SAT/SUN
# W-MON:从指定星期几开始算起,每周
pd.date_range('2020-01-01','2020-12-31',freq='WOM-1THU')
显示结果:
DatetimeIndex(['2020-01-02', '2020-02-06', '2020-03-05', '2020-04-02', '2020-05-07', '2020-06-04', '2020-07-02', '2020-08-06', '2020-09-03', '2020-10-01', '2020-11-05', '2020-12-03'], dtype='datetime64[ns]', freq='WOM-1THU')
#每个月的第三个星期五
pd.date_range('2020-01-01','2020-12-31',freq='WOM-3FRI')
显示结果:
DatetimeIndex(['2020-01-17', '2020-02-21', '2020-03-20', '2020-04-17', '2020-05-15', '2020-06-19', '2020-07-17', '2020-08-21', '2020-09-18', '2020-10-16', '2020-11-20', '2020-12-18'], dtype='datetime64[ns]', freq='WOM-3FRI')
2 datetime类型案例¶
2.1 加载数据集¶
# 某城市报警记录
crime = pd.read_csv('data/crime.csv',parse_dates=['REPORTED_DATE'])
crime
crime.info()
显示结果:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 460911 entries, 0 to 460910 Data columns (total 8 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 OFFENSE_TYPE_ID 460911 non-null object 1 OFFENSE_CATEGORY_ID 460911 non-null object 2 REPORTED_DATE 460911 non-null datetime64[ns] 3 GEO_LON 457296 non-null float64 4 GEO_LAT 457296 non-null float64 5 NEIGHBORHOOD_ID 460911 non-null object 6 IS_CRIME 460911 non-null int64 7 IS_TRAFFIC 460911 non-null int64 dtypes: datetime64[ns](1), float64(2), int64(2), object(3) memory usage: 28.1+ MB
#设置报警时间为索引
crime = crime.set_index('REPORTED_DATE')
crime.head()
2.2 数据查看¶
1 查看某一天的报警记录¶
crime.loc['2016-05-12']
2 查看某一段时间的犯罪记录¶
crime.loc['2015-3-4':'2016-1-1'].sort_index()
3 时间段可以包括小时分钟¶
crime.loc['2015-3-4 22':'2016-1-1 23:45:00'].sort_index()
4 查询凌晨两点到五点的报警记录¶
crime.between_time('2:00', '5:00', include_end=False)
5 查看发生在某个时刻的犯罪记录¶
crime.at_time('5:47')
2.3 分析每周报警记录¶
- 为了统计每周的犯罪数,需要按周分组
1 resample重采样¶
- 可以按照指定时间周期分组
crime.resample('W')
#size查看分组大小
weekly_crimes = crime.resample('W').size()
weekly_crimes
显示结果:
REPORTED_DATE 2012-01-08 877 2012-01-15 1071 2012-01-22 991 2012-01-29 988 2012-02-05 888 ... 2017-09-03 1956 2017-09-10 1733 2017-09-17 1976 2017-09-24 1839 2017-10-01 1059 Freq: W-SUN, Length: 300, dtype: int64
2 检验分组结果¶
len(crime.loc[:'2012-1-8'])
显示结果:
877
len(crime.loc['2012-1-9':'2012-1-15'])
显示结果:
1071
3 调整结果¶
- 也可以把周四作为每周的结束
crime.resample('W-THU').size()
显示结果:
REPORTED_DATE 2012-01-05 462 2012-01-12 1116 2012-01-19 924 2012-01-26 1061 2012-02-02 926 ... 2017-09-07 1803 2017-09-14 1866 2017-09-21 1926 2017-09-28 1720 2017-10-05 28 Freq: W-THU, Length: 301, dtype: int64
4 将按周分组结果可视化¶
weekly_crimes.plot(figsize=(16,4),title='丹佛犯罪情况')
显示结果:
小结¶
- Pandas中,datetime64用来表示时间序列类型
- 时间序列类型的数据可以作为行索引,对应的数据类型是DatetimeIndex类型
- 转换成时间序列类型后,可以按照时间的特点对数据进行处理
- 提取日期的各个部分(月,日,星期...)
- 进行日期运算
- 按照日期范围取值