Pandas日期偏移与转换

5 投票
1 回答
5348 浏览
提问于 2025-04-18 05:55

我想把一个字段当作日期来处理,然后把这个日期改成它所在月份的表示,再把日期往后推一个月,最后以没有时间戳的日期形式呈现出来。结果我写出来的代码看起来太复杂了:

    df['DATE'].apply( lambda d: pd.to_datetime(pd.to_datetime(d).to_period('M').to_timestamp('M')\
                                      - np.timedelta64(1,'M')).date())

这些时间戳是以这种格式的字符串表示:

    2012-09-01 00:00:00

有没有更好的方法呢?谢谢。

1 个回答

9

好吧,你可以不使用apply,而是用向量化的方法来处理(我觉得这样会更好一些):

print df

                  date  x1
0  2010-01-01 00:00:00  10
1  2010-02-01 00:00:00  10
2  2010-03-01 00:00:00  10
3  2010-04-01 00:00:00  10
4  2010-04-01 00:00:00   5
5  2010-05-01 00:00:00   5

df['date'] = (pd.to_datetime(df['date']).values.astype('datetime64[M]')
              - np.timedelta64(1,'M'))
print df

        date  x1
0 2009-12-01  10
1 2010-01-01  10
2 2010-02-01  10
3 2010-03-01  10
4 2010-03-01   5
5 2010-04-01   5

当然,日期还是会是datetime64[ns]格式,因为pandas总是会转换成这个格式。

补充:假设你想要的是上个月的最后一天,而不是上个月的第一天:

df['date'] = (pd.to_datetime(df['date']).values.astype('datetime64[M]')
              - np.timedelta64(1,'D'))
print df

        date  x1
0 2009-11-30  10
1 2009-12-31  10
2 2010-01-31  10
3 2010-02-28  10
4 2010-02-28   5
5 2010-03-31   5

补充:Jeff提到一种更符合pandas风格的方法,就是把日期变成DatetimeIndex,然后使用日期偏移。所以可以这样做:

df['date'] = pd.Index(df['date']).to_datetime() - pd.offsets.MonthBegin(1)
print df

        date  x1
0 2009-12-01  10
1 2010-01-01  10
2 2010-02-01  10
3 2010-03-01  10
4 2010-03-01   5
5 2010-04-01   5

或者获取每个月的最后一天:

df['date'] = pd.Index(df['date']).to_datetime() - pd.offsets.MonthEnd(1)
print df

        date  x1
0 2009-12-31  10
1 2010-01-31  10
2 2010-02-28  10 
3 2010-03-31  10
4 2010-03-31   5
5 2010-04-30   5

撰写回答