2014-05-09 6 views
5

Próbuję zinterpretować pole jako datę, zmienić datę reprezentującą miesiąc, w którym data się pojawia, przesunąć datę o miesiąc, a następnie przedstawić ją jako datę bez znaczników czasu. I skończyło się na tym, który wygląda i czuje się zbyt nieporęczny:Przesunięcie i przeliczenie daty Pandy

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

timestampów są struny w tym formacie:

2012-09-01 00:00:00 

Wszelkie pomysły na lepszy sposób? Dzięki.

Odpowiedz

8

Cóż, można uniknąć zastosowania i zrób to wektorowy (myślę, że sprawia, że ​​nieco ładniejsza):

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 

Oczywiście, terminy będą nadal datetime64[ns] od pandy zawsze konwertuje do tego.

Edit: Załóżmy, że chciał do końca poprzedniego miesiąca zamiast na początku działalności w poprzednim miesiącu:

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 

Edit: Jeff zauważa, że ​​bardziej pandonic sposobem jest, aby data DatetimeIndex i użyj przesunięcia daty. Więc coś takiego:

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 

lub miesiąc końców:

+0

To great.Much szybciej niż 'apply()' Wiesz, jeśli to możliwe jest użycie 'datetime64 [M]' do znaleźć koniec miesiąca zamiast początku? – JAB

+0

Tak, zobacz moją edycję. –

+1

bardziej pandonicznym sposobem jest potraktowanie go jako indeksu i użycie wycofania z odpowiednim przesunięciem, patrz tutaj: http://pandas-docs.github.io/pandas-docs-travis/timeseries.html#dateoffset-objects – Jeff