Bootstrap

pytho机器学习值之处理日期和时间

1.1 把字符串转换成日期

把一个代表日期和时间的字符串向量转换成时间序列数据

解决方案:
使用pandas的to_datatime函数,并通过format参数指定字符串的日期和时间格式。

import numpy as np
import pandas as pd

#创建字符串
date_strings = np.array(['03-04-2005 10:35 pM',
                         '23-05-2010 12:33 PM',
                         '04-09-2009 09:10 AM'])

#转换成datatime类型的数据
for date in date_strings:
    print(pd.to_datetime(date,format = '%d-%m-%Y %I:%M %p'))

result:

2005-04-03 22:35:00
2010-05-23 12:33:00
2009-09-04 09:10:00

常用日期和时间个格式化代码:

代码描述例子
%Y完整的年份2020
%m月,首位空缺时需用0填充09
%d日,首位空缺时需用0填充11
%I小时,首位空缺时需用0填充16
%PAM或PMPM
%M分,首位空缺时需用0填充19
%S秒,首位空缺时需用0填充50

1.2 处理时区

为一组时间序列数据添加或改变时区

如果没有特别指定,pandas的对象都是没有时区的,可以在创建对象时通过tz参数指定时区

import pandas as pd
#创建datetime
pd.Timestamp('2020-09-11 16:27:44', tz = 'Europe/London')

output:

Timestamp('2020-09-11 16:27:44+0100', tz='Europe/London')
date = pd.Timestamp('2020-09-11 16:27:44')
date_in_london = date.tz_localize('Europe/London')
date_in_london

output:

Timestamp('2020-09-11 16:27:44+0100', tz='Europe/London')
  • 转换时区
date_in_london.tz_convert('Africa/Abidjan')

output:

Timestamp('2020-09-11 15:27:44+0000', tz='Africa/Abidjan')

导入all_timezones库就能看到所有代表时区的字符串

1.3 选择日期和时间

从一组日期向量中,选择一个或多个日期
解决方案:
1.使用两个布尔条件句分别设置开始日期和结束日期

import pandas as pd 
dataframe = pd.DataFrame()
dataframe['date'] = pd.date_range('1/1/2019',periods = 100000,freq = 'H')
#筛选出两个日期之间的观察值
dataframe[(dataframe['date'] > '2020-09-11 16:00:00')&
              (dataframe['date'] <='2020-09-11 19:00:00')]

output:

	    date
14873	2020-09-11 17:00:00  
14874	2020-09-11 18:00:00  
14875	2020-09-11 19:00:00  

2.将data(日期)这一列设为数据帧的索引列,然后用loc进行筛选

dataframe = dataframe.set_index(dataframe['date'])
dataframe.loc['2020-09-11 17:00:00':'2020-09-11 19:00:00']

1.4 将日期数据切分成多个特征

用一系列日期和时间数据来创建年、月、日、时、分的特征
解决方案:
使用pandas函数Series.dt的时间属性

import pandas as pd 
dataframe = pd.DataFrame()
dataframe['date'] = pd.date_range('11/09/2020',periods=5,freq = 'W')

dataframe['year'] = dataframe['date'].dt.year
dataframe['month'] = dataframe['date'].dt.month
dataframe['day'] = dataframe['date'].dt.day
dataframe['hour'] = dataframe['date'].dt.hour
dataframe['minute'] = dataframe['date'].dt.minute
dataframe

output:

    date	    year	month  day hour minute
0	2020-11-15	2020	11	15	0	0
1	2020-11-22	2020	11	22	0	0
2	2020-11-29	2020	11	29	0	0
3	2020-12-06	2020	12	6	0	0
4	2020-12-13	2020	12	13	0	0

1.5 计算两个日期之间的时间差

为每个观察值计算两个日期特征之间的时间差
解决方案:
使用pandas对两个日期特征做减法

1.6 对一周之内的各天进行编码

求一个日期向量中的每一个日期是星期几
解决方案:
使用pandas中Series.dt的weekday_name属性

import pandas as pd
dates = pd.Series(pd.date_range("11/09/2002",periods = 3,freq = "M"))
dates.dt.weekday

output:

0    5
1    1
2    4
dtype: int64

dates.dt.weekday_name报错

1.7 创建一个滞后的特征

创建一个滞后n个时间段的特征
解决方案:使用pandas的shift

import pandas as pd
dataframe = pd.DataFrame()

datframe['dates'] = pd.date_range("11/09/2020",periods = 5,freq = "D")
dataframe['stock_price'] = [1.1,2.2,3.3,4.4,5.5]

#让值滞后一行
dataframe['previous_days_stock_price'] = dataframe['stock_price'].shift(1)

dataframe

output:

    dates	   stock_price	previous_days_stock_price
0	2020-11-09	1.1	        NaN
1	2020-11-10	2.2	        1.1
2	2020-11-11	3.3	        2.2
3	2020-11-12	4.4	        3.3
4	2020-11-13	5.5	        4.4

1.8 使用滚动时间窗口

计算一个时间序列数据针对某个滚动时间的统计量
解决方案:

import pandas as pd

time_index = pd.date_range("01/01/2020",periods = 5,freq = "M")
#创建数据帧,设置索引
dataframe = pd.DataFrame(index = time_index)
#创建特征
dataframe['Stock_price'] = [1,2,3,4,5]

#计算滚动平均值
dataframe.rolling(window = 2).mean()

output:


            Stock_price
2020-01-31	NaN
2020-02-29	1.5
2020-03-31	2.5
2020-04-30	3.5
2020-05-31	4.5

滚动平均值常用于对时间序列数据做平滑处理,因为使用整个时间窗口的平均值能削弱短期波动的影响。

1.9 处理时间序列中的缺失值

处理时间序列中的缺失值
解决方案:针对时间序列数据,可以使用插值法来填充由缺失值造成的数据缺口。

import pandas as pd
import numpy as np

#创建日期
time_index = pd.date_range("01/01/2020",periods = 5,freq = "M")

#创建数据帧,设置索引
dataframe = pd.DataFrame(index = time_index)

#创建带缺数据的特征
dataframe['Sales'] = [1.0,2.0,np.nan,np.nan,5.0]

#对数据进行插值
dataframe.interpolate()

output:

	        Sales
2020-01-31	1.0
2020-02-29	2.0
2020-03-31	3.0
2020-04-30	4.0
2020-05-31	5.0

向前填充:

dataframe.ffill()

output:

	        Sales
2020-01-31	1.0
2020-02-29	2.0
2020-03-31	2.0
2020-04-30	2.0
2020-05-31	5.0

向后填充:

dataframe.bfill()

output:

            Sales
2020-01-31	1.0
2020-02-29	2.0
2020-03-31	5.0
2020-04-30	5.0
2020-05-31	5.0

如果已知点之间的线是非线性的,可以使用interpolate的method参数来指定插值方式:

dataframe.interpolate(method = "quadratic")

output:

2020-01-31	1.000000
2020-02-29	2.000000
2020-03-31	3.040158
2020-04-30	4.018418
2020-05-31	5.000000

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;