python-3.x - 根据给定日期提取时间间隔的开始和结束
问题描述
对于df
带有日期的列(都是过去的),我需要用给定日期周围的开始日期和结束日期替换两列。对于每一df
行,有两列包含当前(相对于今天2021-4-9
)的开始日期和结束日期,可以是以下两个确切的六个月间隔中的任何一个:
2020-11-15 2021-5-15
2021-2-15 2021-8-15
示例:如果过去的某一天是1995-06-01
,则具有间隔的列将需要包含1995-05-15 1995-11-15
或1995-02-15 1995-08-15
取决于当前间隔中的月份。
有:
df = pd.DataFrame({'date': ['2016-6-10', '1995-6-1', '2013-10-12'],
'current_start_date': ['2020-11-15', '2020-11-15', '2021-2-15'],
'current_end_date': ['2021-5-15', '2021-5-15', '2021-8-15']})
df[['date', 'current_start_date', 'current_end_date']] = df[['date', 'current_start_date', 'current_end_date']].apply(pd.to_datetime)
需要:
df = pd.DataFrame({'date': ['2016-6-10', '1995-6-1', '2013-10-12'],
'original_start_date': ['2016-5-15', '1995-5-15', '2013-8-15'],
'original_end_date': ['2016-11-15', '1995-11-15', '2014-2-15']})
df[['date', 'original_start_date', 'original_end_date']] = df[['date', 'original_start_date', 'original_end_date']].apply(pd.to_datetime)
解决方案
这可以用np.sort()
和向量化为 3 行np.where()
:
sort
开始/结束日期对(重置为同一年以仅考虑月/日)where
发生date
在开始日期之前,交换开始/结束日期并减少开始年份where
发生date
在结束日期之后,交换开始/结束日期并增加结束年份
date = lambda Y, m: pd.to_datetime(Y.astype(str) + m.astype(str).str.zfill(2) + '15')
#1 sort start/end date pairs (axis=0)
df[['current_start_date', 'current_end_date']] = pd.DataFrame(np.sort([
date(df.date.dt.year, df.current_start_date.dt.month),
date(df.date.dt.year, df.current_end_date.dt.month),
], axis=0).T)
#2 where date occurs before start date, swap and decrement start year
df['original_start_date'], df['original_end_date'] = np.where(df.date < df.current_start_date,
[df.current_end_date - pd.DateOffset(years=1), df.current_start_date],
[df.current_start_date, df.current_end_date])
#3 where date occurs after end date, swap and increment end year
df['original_start_date'], df['original_end_date'] = np.where(df.date > df.current_end_date,
[df.current_end_date, df.current_start_date + pd.DateOffset(years=1)],
[df.original_start_date, df.original_end_date])
df = df.drop(columns=['current_start_date', 'current_end_date'])
# date original_start_date original_end_date
# 0 2016-06-10 2016-05-15 2016-11-15
# 1 1995-06-01 1995-05-15 1995-11-15
# 2 2013-10-12 2013-08-15 2014-02-15
# 3 1998-12-01 1998-11-15 1999-05-15
# 4 1998-01-01 1997-11-15 1998-05-15
# 5 1998-05-14 1997-11-15 1998-05-15
# 6 1998-05-16 1998-05-15 1998-11-15
# 7 1990-11-15 1990-05-15 1990-11-15
这比df.apply()
:
推荐阅读
- google-apps-script - Apps 脚本通过 MailApp 发送整张表格
- powershell - 当经理是联系人时获取 ADUser 的经理。不是帐户
- python - 在没有 conda 的情况下安装 cudf
- powershell - 术语“参数”未被识别为 cmdlet 的名称
- javascript - 通过 Selenium 将数据从 websocket / js 脚本推送到 python 脚本
- apache - Gitea Git-LFS HTTP 413 推送大文件时出错
- html - React 中的 CSS 转换剪切按钮
- python - 使用python自动创建csv文件
- math - 找出一个点在倾斜网格中的哪个单元格
- c# - 将对象属性从 C# 函数返回到 Blazor Web 元素