本文讨论并演示了如何使用 Python 快速设计一些常见的日期功能。
微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩
也许像我一样,你在 Python 中处理数据时会经常处理日期。也许,您对在 Python 中处理日期感到沮丧,并且发现您经常查阅文档而无法一遍又一遍地做同样的事情。
就像任何编写代码并发现自己多次做同一件事的人一样,我想通过自动化一些常见的日期处理任务以及一些简单而频繁的特征工程来让我的生活更轻松,这样我的常见日期解析和给定日期的处理任务可以通过单个函数调用来完成。然后我可以在之后的给定时间选择我有兴趣提取的特征。
此日期处理是通过使用单个 Python 函数完成的,该函数仅接受格式为 ' 的单个日期字符串 YYYY-MM-DD' (因为这就是日期的格式),并返回一个由(当前)18 个键/值特征对组成的字典。其中一些键非常简单(例如解析的四个 4 日期年份),而其他键是经过设计的(例如日期是否为公共假期)。如果您发现此代码完全有用,您应该能够弄清楚如何更改或扩展它以满足您的需要。有关您可能想要编写代码生成的其他日期/时间相关功能的一些想法, 请查看这篇文章 。(https://www.kdnuggets.com/2021/04/feature-engineering-datetime-variables-data-science-machine-learning.html)
大部分功能是使用 Python 完成的 datetime模块,其中大部分依赖于 strftime()方法。然而,真正的好处是对于相同的重复查询有一个标准的、自动化的方法。
唯一使用的非标准库是 holidays,一个“快速、高效的 Python 库,用于即时生成国家、省和州特定的假期集。” 虽然图书馆可以容纳大量的国家和次国家节假日,但我在此示例中使用了美国国定假日。快速浏览一下项目的文档和下面的代码,您将很容易确定如何在需要时进行更改。(https://pypi.org/project/holidays/)
import datetime, re, sys, holidays
def process_date(input_str: str) -> {}:
"""Processes and engineers simple features for date strings
Parameters:
input_str (str): Date string of format '2021-07-14'
Returns:
dict: Dictionary of processed date features
"""
# Validate date string input
regex = re.compile(r'\d{4}-\d{2}-\d{2}')
if not re.match(regex, input_str):
print("Invalid date format")
sys.exit(1)
# Process date features
my_date = datetime.datetime.strptime(input_str, '%Y-%m-%d').date()
now = datetime.datetime.now().date()
date_feats = {}
date_feats['date'] = input_str
date_feats['year'] = my_date.strftime('%Y')
date_feats['year_s'] = my_date.strftime('%y')
date_feats['month_num'] = my_date.strftime('%m')
date_feats['month_text_l'] = my_date.strftime('%B')
date_feats['month_text_s'] = my_date.strftime('%b')
date_feats['dom'] = my_date.strftime('%d')
date_feats['doy'] = my_date.strftime('%j')
date_feats['woy'] = my_date.strftime('%W')
# Fixing day of week to start on Mon (1), end on Sun (7)
dow = my_date.strftime('%w')
if dow == '0': dow = 7
date_feats['dow_num'] = dow
if dow == '1':
date_feats['dow_text_l'] = 'Monday'
date_feats['dow_text_s'] = 'Mon'
if dow == '2':
date_feats['dow_text_l'] = 'Tuesday'
date_feats['dow_text_s'] = 'Tue'
if dow == '3':
date_feats['dow_text_l'] = 'Wednesday'
date_feats['dow_text_s'] = 'Wed'
if dow == '4':
date_feats['dow_text_l'] = 'Thursday'
date_feats['dow_text_s'] = 'Thu'
if dow == '5':
date_feats['dow_text_l'] = 'Friday'
date_feats['dow_text_s'] = 'Fri'
if dow == '6':
date_feats['dow_text_l'] = 'Saturday'
date_feats['dow_text_s'] = 'Sat'
if dow == '7':
date_feats['dow_text_l'] = 'Sunday'
date_feats['dow_text_s'] = 'Sun'
if int(dow) > 5:
date_feats['is_weekday'] = False
date_feats['is_weekend'] = True
else:
date_feats['is_weekday'] = True
date_feats['is_weekend'] = False
# Check date in relation to holidays
us_holidays = holidays.UnitedStates()
date_feats['is_holiday'] = input_str in us_holidays
date_feats['is_day_before_holiday'] = my_date + datetime.timedelta(days=1) in us_holidays
date_feats['is_day_after_holiday'] = my_date - datetime.timedelta(days=1) in us_holidays
# Days from today
date_feats['days_from_today'] = (my_date - now).days
return date_feats
_l和 _s后缀分别指“长版”和“短版”
默认情况下,Python 将星期几视为从星期日 (0) 开始,到星期六 (6) 结束;对我和我的处理来说,周从周一开始,到周日结束——我不需要第 0 天(而不是从第 1 天开始一周)——所以这需要改变
工作日/周末功能很容易创建
假期相关的功能很容易使用 holidays库,并进行简单的日期加减;再次,替换其他国家或次国家的假期(或添加到现有的)将很容易做到
一个 days_from_today特征是用另一行或 2 行简单的日期数学创建的;负数是给定日期 在 今天之前的天数,而正数是从今天 到 给定日期
例如,我个人不需要 is_end_of_month功能,但是此时您应该能够看到如何将其添加到上述代码中相对容易。自己尝试一些定制。
现在让我们测试一下。我们将处理一个日期并打印出返回的内容,即完整的键值特征对字典。
import pprint
my_date = process_date('2021-07-20')
pprint.pprint(my_date)
{'date': '2021-07-20', 'days_from_today': 6, 'dom': '20', 'dow_num': '2', 'dow_text_l': 'Tuesday', 'dow_text_s': 'Tue', 'doy': '201', 'is_day_after_holiday': False, 'is_day_before_holiday': False, 'is_holiday': False, 'is_weekday': True, 'is_weekend': False, 'month_num': '07', 'month_text_l': 'July', 'month_text_s': 'Jul', 'woy': '29', 'year': '2021', 'year_s': '21'}
在这里,您可以看到功能键的完整列表以及相应的值。现在,在正常情况下,我不需要打印整个字典,而是获取特定键或一组键的值。
我们可以用下面的代码演示这可能如何实际工作。我们将创建一个日期列表,然后逐个处理这个日期列表,最终创建一个包含已处理日期特征的 Pandas 数据框,并将其打印到屏幕上。
import pandas as pd
dates = ['2021-01-01', '2020-04-04', '1993-05-11', '2002-07-19', '2024-11-03', '2050-12-25']
df = pd.DataFrame()
for d in dates:
my_date = process_date(d)
features = [my_date['date'],
my_date['year'],
my_date['month_num'],
my_date['month_text_s'],
my_date['dom'],
my_date['doy'],
my_date['woy'],
my_date['is_weekend'],
my_date['is_holiday'],
my_date['days_from_today']]
ds = pd.Series(features)
df = df.append(ds, ignore_index=True)
df.rename(columns={0: 'date',
1: 'year',
2: 'month_num',
3: 'month',
4: 'day_of_month',
5: 'day_of_year',
6: 'week_of_year',
7: 'is_weekend',
8: 'is_holiday',
9: 'days_from_today'}, inplace=True)
df.set_index('date', inplace=True)
print(df)
year month_num month day_of_month day_of_year week_of_year is_weekend is_holiday days_from_today date 2021-01-01 2021 01 Jan 01 001 00 0.0 1.0 -194.0 2020-04-04 2020 04 Apr 04 095 13 1.0 0.0 -466.0 1993-05-11 1993 05 May 11 131 19 0.0 0.0 -10291.0 2002-07-19 2002 07 Jul 19 200 28 0.0 0.0 -6935.0 2024-11-03 2024 11 Nov 03 308 44 1.0 0.0 1208.0 2050-12-25 2050 12 Dec 25 359 51 1.0 1.0 10756.0
这个数据框有望让您更好地了解此功能在实践中的用途。
祝你好运,数据处理愉快。
参考文章:https://www.kdnuggets.com/2021/08/engineer-date-features-python.html
https://item.jd.com/13284890.html
《Python从入门到精通(第2版)》从初学者角度出发,通过通俗易懂的语言、丰富多彩的实例,详细介绍了使用Python进行程序开发应该掌握的各方面技术。全书共分23章,包括初识Python、Python语言基础、运算符与表达式、流程控制语句、列表和元组、字典和集合、字符串、Python中使用正则表达式、函数、面向对象程序设计、模块、异常处理及程序调试、文件及目录操作、操作数据库、GUI界面编程、Pygame游戏编程、网络爬虫开发、使用进程和线程、网络编程、Web编程、Flask框架、e起去旅行网站、AI图像识别工具等内容。所有知识都结合具体实例进行介绍,涉及的程序代码都给出了详细的注释,读者可轻松领会Python程序开发的精髓,快速提升开发技能。除此之外,该书还附配了243集高清教学微视频及PPT电子教案。
《Python从入门到精通(第2版)》可作为软件开发入门者的学习用书,也可作为高等院校相关专业的教学参考用书,还可供开发人员查阅、参考使用。
这本书有如下特色:
循序渐进,实战讲述
243集教学微课视频,39小时知识点精讲,可听可看,随时随地扫码学
趣味解读,易教易学
赠送Python实战训练背记手册
在线解答,高效学习
企业QQ、QQ群在线答疑,明日学院社区答疑。
每周清大文森学堂在线直播答疑。
精彩回顾
Python是如何跑起来的?从字节码说起
【案例】如何使用Flask构建天气预报
手把手教你创建简单的Python Flask
微信搜索关注《Python学研大本营》
访问【IT今日热榜】,发现每日技术热点