2014-05-09 127 views
5

我想解釋一個字段作爲日期,更改日期以表示日期出現的月份,將日期抵消一個月,然後將其表示爲沒有時間戳的日期。我已經結束了這個看起來和感覺太笨重:熊貓日期抵消和轉換

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 

任何想法更好的方法?謝謝。

回答

8

嗯,你能避免申請並做到這一點矢量(我認爲這使得它有點爽):

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],因爲熊貓總是轉換爲。

編輯:假設你想前一個月,而不是以前一個月的beggining結束:

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 

編輯:傑夫指出,更pandonic的辦法就是讓日期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 

或一個月結束:

+0

這是great.Much快於'適用()'你知道是否可以使用'datetime64 [M]'來找到月底而不是開始? – JAB

+0

是的,看我的編輯。 –

+1

一個更潘多祿的方式是視爲一個索引和回滾與適當的偏移看到這裏:http://pandas-docs.github.io/pandas-docs-travis/timeseries.html#dateoffset-objects – Jeff