处理日期和时间
文章目录
该文章内容为《Pandas数据分析实战》的学习笔记
引入Timestap对象
Python如何处理日期时间型数据
为了减少内存消耗,Python默认不自动加载其标准库模块,需要自己导入
import datetime as dt
import pandas as pd
让我们来回忆一下模块中的四个类:date、time、datetime和timedelta
date对象代表历史中的一天
birthday = dt.date(2005, 8, 8)
birthday = dt.date(year = 2005, month = 8, day = 8)
# 访问
birthday.year
birthday.month
birthday.day
date对象是不可变的,创建之后无法更改
time对象表示一天中的特定时间,不关心具体日期
alarm_clock = dt.time(6, 43, 25)
alarm_clock = dt.time(hour = 6, minute = 43, second = 25)
构造的时候默认参数是0,也就是你不传入哪个哪个将被设置为0
# 访问
alarm_clock.hour
alarm_clock.minute
alarm_clock.second
datetime对象,它同时包含日期和时间
moon_landing = dt.datetime(1969, 7, 20, 22, 56, 20)
各种操作和前面的date、time类类似
其中构建的时候year、month和day参数是必须的。与时间相关的参数是可选的,这些参数的默认值为0
Pandas如何处理日期时间型数据
Pandas引入了Timestamp对象来代替Python的datetime对象。它具有更多的功能,Timestamp的构造函数接受和datetime的构造函数相同的参数
pd.Timestamp(2005, 8, 8)
Timestamp的构造函数更加灵活可以接受各种输入
pd.Timestamp("2015-03-31")
pd.Timestamp("2015/03/31")
pd.Timestamp("03/31/2015")
pd.Timestamp("2021-03-08 6:13:29 PM")
my_time = pd.Timestamp(dt.datetime(2000, 2, 3, 21, 35, 22)) # 还可以接受datetime对象
# 访问
my_time.year
在DataetimeIndex中存储多个时间戳
DataetimeIndex是用于存储Timestamp对象的索引
timestamps = [
pd.Timestamp("2020-01-01"),
pd.Timestamp("2020-02-01"),
pd.Timestamp("2020-03-01"),
]
pd.Series([1, 2, 3], index=timestamps)
同样的Timestamp也可以换为datetime
使用DatetimeProperties对象
disney = pd.read_csv("pandas-in-action-master/chapter_11_working_with_dates_and_times/disney.csv", parse_dates=["Date"])
disney.head()
访问是哪一天
disney["Date"].dt.day
查看是星期几
disney["Date"].dt.dayofweek
如果想要的是工作日名称,可以使用day_name
方法
disney["Date"].dt.day_name()
month_name
方法返回一个带有日期月份名称的Series
disney["Date"].dt.month_name()
is_quarter_start
方法属性返回一个布尔Series,其中True表示该记录日期为季度开始日。其中四个季度分别从1月1日、4月1日、7月1日和10月1日开始
disney["Date"].dt.is_quarter_start
disney[disney["Date"].dt.is_quarter_start]
同时还有
is_quarter_end
、is_month_start
、is_month_end
、is_year_start
和is_year_end
方法
使用持续时间进行加减
Pandas中可以使用DateOffset对象添加或减去一段的持续时间。其构造函数接受years、months和days等参数,还可以接受时分秒等参数
pd.DateOffset(days = 5)
比如说我们现在要将disney中所有的日期加五天
(disney["Date"] + pd.DateOffset(days = 5)).head()
(disney["Date"] - pd.DateOffset(years = 1, month = 3, days = 5, hours = 6, minutes = 3)).head()
日期偏移
前面提到的DateOffset适合将每个日期添加或减去一致的事件量,而我们经常存在一些更加动态的计算
MonthEnd
方法可以将每个日期舍入到月末,其中+为向前移动(到当前月末),-向后移动(到上个月末)
disney["Date"] + pd.offsets.MonthEnd()
还有MonthBegin
和BMonthEnd
,其中后者是偏移到当月的最后一个工作日
Timedelta对象
Timedelta表示持续一段时间-两个试驾之间的差值,其构造函数接受时间单位的关键字传入
duration = pd.Timedelta(
days = 8,
hours = 7,
minutes = 6,
seconds = 5,
)
还可以用一个Timestamp减去另一个Timestamp得到一个存储时间差的Timedelta
pd.Timestamp("1999-02-05") - pd.Timestamp("1998-04-07")
通过这个我们还可以大规模求时间差值
deliveries = pd.read_csv("pandas-in-action-master/chapter_11_working_with_dates_and_times/deliveries.csv")
deliveries["order_date"] = pd.to_datetime(deliveries["order_date"])
deliveries["delivery_date"] = pd.to_datetime(deliveries["delivery_date"])
deliveries.head()
deliveries["duration"] = (deliveries["delivery_date"] - deliveries["order_date"])
deliveries.head()
Timedelta也提供数学方法
deliveries["duration"].max()
deliveries["duration"].min()
deliveries["duration"].mean()
deliveries["duration"].std()
还可以与固定持续时间进行比较,比如下面找到交付时间大于365天都记录
deliveries[deliveries["duration"] > "365 days"]
代码挑战
citi_bike = pd.read_csv("pandas-in-action-master/chapter_11_working_with_dates_and_times/citibike.csv")
citi_bike.head()
本章的问题如下:
- 将
start_time
和stop_time
列转换为日期时间类型(Timestamp
)而不是字符串。 - 计算一周中每天的骑行次数,并计算哪个工作日的骑行次数最多。使用
start_time
列作为起点。 - 计算一个月中,每周的骑行次数。为此,请将
start_time
列中的每个日期舍入到其上一个或当前的星期一。假设每周从星期一开始,到星期日结束。因此,在当前数据集内,6 月的第一周将是 6 月 1 日星期一到 6 月 7 日星期日。 - 计算每次骑行的持续时间,并将结果保存到新的
duration
列。 - 计算骑自行车的平均持续时间。
- 从数据集中找到骑行时间最长的 5 条记录。
解决方案
# 1
citi_bike["start_time"] = pd.to_datetime(citi_bike["start_time"])
citi_bike["stop_time"] = pd.to_datetime(citi_bike["stop_time"])
citi_bike.head()
# 2
citi_bike["start_time"].dt.day_name().value_counts()
# 3
days_away_from_monday = citi_bike["start_time"].dt.dayofweek
dates_rounded_to_monday = citi_bike["start_time"] - pd.to_timedelta(days_away_from_monday, unit = "day")
dates_rounded_to_monday.dt.date.value_counts()
# 4
citi_bike["duration"] = (citi_bike["stop_time"] - citi_bike["start_time"])
citi_bike.head()
# 5
citi_bike["duration"].mean()
# 6
citi_bike.sort_values(by = "duration", ascending=False).head(5)
关注公众号小辛到处学,发送1,获取文中的数据资源