2015-12-14 15 views
6

Ho il foll. dataframe:Conversione anno e giorno dell'anno in indice datetime in panda

year doy 
2000 49 
2000 65 
2000 81 
2001 97 
2001 113 
2001 129 
2001 145 
2001 161 

Voglio creare un indice per questo dataframe. L'indice dovrebbe essere un indice datetime. Ecco cosa sto facendo:

df.index = pandas.DatetimeIndex(df['doy'].apply(lambda x: date(2000, 1, 1)+ relativedelta(days=int(x)-1))) 

Tuttavia, questo crea un indice datetime che utilizza solo 2000 come anno. Come posso ripararlo?

risposta

7

È possibile utilizzare NumPy datetime64/timedelta64 arithmetic per trovare le date desiderate:

In [97]: (np.asarray(df['year'], dtype='datetime64[Y]')-1970)+(np.asarray(df['doy'], dtype='timedelta64[D]')-1) 
Out[97]: 
array(['2000-02-18', '2000-03-05', '2000-03-21', '2001-04-07', 
     '2001-04-23', '2001-05-09', '2001-05-25', '2001-06-10'], dtype='datetime64[D]') 

Dal comporre date indicate varie parti del date (ad esempio anni, mesi, giorni, settimane, ore, etc.) è un problema comune, qui è una funzione di utilità per rendere più facile:

def compose_date(years, months=1, days=1, weeks=None, hours=None, minutes=None, 
       seconds=None, milliseconds=None, microseconds=None, nanoseconds=None): 
    years = np.asarray(years) - 1970 
    months = np.asarray(months) - 1 
    days = np.asarray(days) - 1 
    types = ('<M8[Y]', '<m8[M]', '<m8[D]', '<m8[W]', '<m8[h]', 
      '<m8[m]', '<m8[s]', '<m8[ms]', '<m8[us]', '<m8[ns]') 
    vals = (years, months, days, weeks, hours, minutes, seconds, 
      milliseconds, microseconds, nanoseconds) 
    return sum(np.asarray(v, dtype=t) for t, v in zip(types, vals) 
       if v is not None) 

df = pd.DataFrame({'doy': [49, 65, 81, 97, 113, 129, 145, 161], 
        'year': [2000, 2000, 2000, 2001, 2001, 2001, 2001, 2001]}) 

df.index = compose_date(df['year'], days=df['doy']) 

cede

  doy year 
2000-02-18 49 2000 
2000-03-05 65 2000 
2000-03-21 81 2000 
2001-04-07 97 2001 
2001-04-23 113 2001 
2001-05-09 129 2001 
2001-05-25 145 2001 
2001-06-10 161 2001 
+0

grazie @unutbu! c'è qualcosa di speciale nel 1970? potrei usare 1900 o 2000? – user308827

+1

'1970-01-01 00:00:00 UTC' è la [Unix Epoch] (https://en.wikipedia.org/wiki/Unix_time). Poiché 'np.array ([0], dtype = 'datetime64 [Y]')' restituisce 'array (['1970'], dtype = 'datetime64 [Y]')', dobbiamo sottrarre 1970. – unutbu

+0

grazie questo è molto chiaro! – user308827

5

Puoi utilizzare lo specificatore di data %j per estrarre il giorno dell'anno. Quindi unisci le due colonne, sposta l'anno e converti in datetime!

pd.to_datetime(df['year'] * 1000 + df['doy'], format='%Y%j') 

rendimenti

0 2000-02-18 
1 2000-03-05 
2 2000-03-21 
3 2001-04-07 
4 2001-04-23 
5 2001-05-09 
6 2001-05-25 
7 2001-06-10 
dtype: datetime64[ns] 
Problemi correlati