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