【问题标题】:date - offsets.MonthBegin(1) returns prior month if the date is the first of the monthdate - offsets.MonthBegin(1) 如果日期是本月的第一天,则返回上个月
【发布时间】:2026-02-09 03:35:01
【问题描述】:

我正在尝试为 pandas 数据框创建月份列。将“19 年 10 月 21 日”更改为“19 年 10 月 1 日”。以下方法适用于大多数日期,但会将月初更改为上个月:

ts = '2016-03-05 00:20:02'
pd.to_datetime(ts) - pd.offsets.MonthBegin(1)
# returns 'Timestamp('2016-03-01 00:20:02')'

ts = '2016-03-01 00:20:02'
pd.to_datetime(ts) - pd.offsets.MonthBegin(1)
# returns 'Timestamp('2016-02-01 00:20:02')'

ts = '2016-03-01 00:20:02'
pd.to_datetime(ts) + pd.offsets.MonthBegin(1) - pd.offsets.MonthBegin(1)
# returns 'Timestamp('2016-03-01 00:20:02')'

我在第三个示例中找到了解决方案。先更新到月底再更新回月初。考虑到这种转换的普遍性,我觉得应该有一种更 Pythonic 的方式来做到这一点。

【问题讨论】:

  • pd.to_datetime(ts) + pd.offsets.DateOffset(day=1)
  • 添加到@MichaelGardner 的评论中,将hour=0,minute=0,second=0 添加到参数列表以设置一天开始的时间。

标签: python pandas


【解决方案1】:

所需的功能由rollback 函数提供:

ts1 = '2016-03-05 00:20:02'
ts2 = '2016-03-01 00:20:02'
ts3 = '2016-03-31 00:20:02'
pd.offsets.MonthBegin().rollback(ts1)
#Timestamp('2016-03-01 00:20:02')
pd.offsets.MonthBegin().rollback(ts2)
#Timestamp('2016-03-01 00:20:02')
pd.offsets.MonthBegin().rollback(ts3)
#Timestamp('2016-03-01 00:20:02')


如果您有一个 datetime 列并希望将其缩减为月,您还可以临时更改底层 numpy datetime64 类型的精度:
df = pd.DataFrame({'Date': ['2016-03-05 00:20:02', '2016-03-01 00:20:02', '2016-03-31 00:20:02']})
df.Date = pd.to_datetime(df.Date)

df['Month'] = df.Date.astype('<M8[M]')
print(df)
#                 Date      Month
#0 2016-03-05 00:20:02 2016-03-01
#1 2016-03-01 00:20:02 2016-03-01
#2 2016-03-31 00:20:02 2016-03-01

(取自this SO答案)

【讨论】:

    最近更新 更多