处理日期和时间
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 |
%P | AM或PM | PM |
%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