Machine Learning with Python Cookbook 学习笔记 第7章

Chapter 7. Handling Dates and Times

前言

7.0 Introduction

  • 日期和时间是机器学习中常见要处理的类型
  • pandas 库中的时间序列工具,它集中了许多其他库的功能。

7.1 Converting Strings to Dates

  • 转换字符串为时间
  • pandas’ to_datetime

strToDate.py

import numpy as np
import pandas as pd

date_strings = np.array([
    '03-04-2005 11:35 PM',
    '23-05-2010 12:01 AM',
    '04-09-2009 09:09 PM'
])

# 转换 datetimes
print([pd.to_datetime(date, format='%d-%m-%Y %I:%M %p') for date in date_strings])


# coerce设置时 不会raise error 而会输出NaT
date_strings = np.append(date_strings,["13-13-3333 25:61 PP"])
print([pd.to_datetime(date, format='%d-%m-%Y %I:%M %p', errors='coerce') for date in date_strings])

image-20220718114919034

Discussion
  • pandas’ to_datetime可以将字符串转换为时间

  • 可以使用 format 参数来指定字符串的确切格式。

  • 创建的日期格式

    CodeDescriptionExample
    %YFull year2001
    %mMonth w/ zero padding04
    %dDay of the month w/ zero padding09
    %IHour (12hr clock) w/ zero padding02
    %pAM or PMAM
    %MMinute w/ zero padding05
    %SSecond w/ zero padding09

7.2 Handling Time Zones

  • 处理时区
  • 如果未指定,pandas 对象没有时区。 但是,我们可以在创建过程中使用 tz 添加时区:

timeZone.py

import pandas as pd
print(pd.Timestamp('2017-05-01 06:00:00', tz='Europe/London'))

date = pd.Timestamp('2017-05-01 06:00:00')
# 设置 time zone
date_in_london = date.tz_localize('Europe/London')
# 打印
print(date_in_london)

# 更改时区 time zone
print(date_in_london.tz_convert('Africa/Abidjan'))

# 通过pd一次性创建3个时间段
dates = pd.Series(pd.date_range('2/2/2002', periods=3, freq='M'))
# 设置时区
print(dates.dt.tz_localize('Africa/Abidjan'))

image-20220718203729330

Discussion
  • 建议使用 pytz 库的字符串
  • 导入 all_timezones 查看所有用于表示时区的字符串:
# Load library
from pytz import all_timezones
# 展示前两个时区
print(all_timezones[0:2])

image-20220718204818920

7.3 Selecting Dates and Times

  • 从一组日期中选择出特定的日期
  • pandas dataFrame的切片访问

selectTime.py

# Load library
import pandas as pd
# 创建空的DataFrame
dataframe = pd.DataFrame()
# 填充数据
dataframe['date'] = pd.date_range('1/1/2001', periods=100000, freq='H')
# Select 
print(dataframe[(dataframe['date'] > '2002-1-1 01:00:00') &
(dataframe['date'] <= '2002-1-1 04:00:00')])

image-20220718205738464

Discussion
  • bool条件值或者切片
  • 作者认为在大数据时应该使用切片,而数据量较小的时候使用bool值访问更加合适

7.4 Breaking Up Date Data into Multiple Features

  • 将日期拆解成多个特征
  • pandas Series.dt

seriesDt.py

# Load library
import pandas as pd
# 空的dataFrame
dataframe = pd.DataFrame()
# 创建 150个数据
dataframe['date'] = pd.date_range('1/1/2001', periods=150, freq='W')
# 使用dt拆解成年月日小时分钟
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
# Show
print(dataframe.head(3))

image-20220718210303226

Discussion
  • 分解时间作者认为有时很有用比如只考察某样事物一年间每月的变化

7.5 Calculating the Difference Between Dates

  • 想要计算时间差
  • pandas

timestamp.py

# Load library
import pandas as pd
# Create data frame
dataframe = pd.DataFrame()
# 创建两个时间
dataframe['Arrived'] = [pd.Timestamp('01-01-2017'), pd.Timestamp('01-04-2017')]
dataframe['Left'] = [pd.Timestamp('01-01-2017'), pd.Timestamp('01-06-2017')]
# 计算持续时间
print(dataframe['Left'] - dataframe['Arrived'])

# 计算持续时间
print(pd.Series(delta.days for delta in (dataframe['Left'] - dataframe['Arrived'])))

image-20220718211219675

Discussion
  • 计算时间差值很有用
  • pandas中的TimeDelta使得计算时间差值很简单
# 计算时间差
timedelta = pd.Timedelta('2 days 2 hours 15 minutes 30 seconds')
print(timedelta)

image-20220718211626892

7.6 Encoding Days of the Week

  • 对星期编码
  • Series.dt

weekdays.py

# Load library
import pandas as pd
# Create dates
dates = pd.Series(pd.date_range("2/2/2002", periods=3, freq="M"))
# Show days of the week
print(dates.dt.weekday_name)
# Show days of the week
print(dates.dt.weekday)

报错

image-20220718212047131

根据查阅资料weekday_name已经被废弃,改为day_name

# Load library
import pandas as pd
# Create dates
dates = pd.Series(pd.date_range("2/2/2002", periods=3, freq="M"))
# 星期几
print(dates.dt.day_name())
# 数字编号
print(dates.dt.weekday)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j62bKYDA-1658154228711)(C:\Users\12587\AppData\Roaming\Typora\typora-user-images\image-20220718213120073.png)]

Discussion
  • 对于分析星期类的问题,pandas的转换会很有帮助

7.7 Creating a Lagged Feature

  • 创建滞后特征
  • 使用pandas库的shift
# Load library
import pandas as pd
# Create data frame
dataframe = pd.DataFrame()
# Create data
dataframe["dates"] = pd.date_range("1/1/2001", 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
print(dataframe)

image-20220718213839590

Discussion
  • 什么是Lagged Feature?

    • 数据通常基于有规律的间隔时间段(例如,每天、每小时、每三个小时),我们有兴趣使用过去的值进行预测,而这些过去的特征就可以称作滞后特征(Lagged Feature)
  • 在我们的示例中因为往前移了一天,第一行没有数据,所以是NaN;

7.8 Using Rolling Time Windows

  • 计算这些流动时间的统计数据

statistic.py

# Load library
import pandas as pd
# Create datetimes
time_index = pd.date_range("01/01/2010", periods=5, freq="M")
# 设置index
dataframe = pd.DataFrame(index=time_index)
# 新建一个特征
dataframe["Stock_Price"] = [1,2,3,4,5]
# 窗口大小为2,求出窗口时间中的平均值
print(dataframe.rolling(window=2).mean())

image-20220718214653455

Discussion
  • 滚动时间窗口包含连续的一些时间,然后一次次的移动
  • 每次可以求出窗口内的统计数据

7.9 Handling Missing Data in Time Series

  • 处理丢失数据
  • 类似于之前处理丢失数据的方式
  • 我们对于时间数据还可以使用插值法

handlingMissing.py

# Load libraries
import pandas as pd
import numpy as np

# Create date
time_index = pd.date_range("01/01/2010", periods=5, freq="M")
# set index
dataframe = pd.DataFrame(index=time_index)
# 创建一组有缺失的数据
dataframe["Sales"] = [1.0, 2.0, np.nan, np.nan, 5.0]
# 插入缺失值
print(dataframe.interpolate())

# 前值填充
print(dataframe.ffill())

# 后值填充
print(dataframe.bfill())

image-20220718215920807

Discussion
  • 插值是一种填补由缺失值引起的空白的技术,实际上是在与空白接壤的已知值之间绘制一条直线或曲线,并使用该直线或曲线来预测合理的值。

    • 我们的解决方案中,两个缺失值的差距以 2.0 和 5.0 为界。通过拟合从 2.0 到 5.0 的线,我们可以对介于 3.0 和 4.0 之间的两个缺失值做出合理的猜测。

    • 如果我们认为两个已知点之间的线是非线性的,我们可以使用 interpolate 的方法来指定插值方法:

    # 非线性 结果见下图
    print(dataframe.interpolate(method="quadratic"))
    
  • 在某些情况下,我们的缺失值差距很大,并且不想在整个差距中插入值。在这些情况下,我们可以使用 limit 来限制插值的数量,使用 limit_direction 来设置是否从间隙之前的最后一个已知值向前插值,

# 限制
print(dataframe.interpolate(limit=1, limit_direction="forward"))

image-20220718221132787

下一章:(95条消息) Machine Learning with Python Cookbook 学习笔记 第8章_五舍橘橘的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值