2015-12-14 42 views
6

我有這個foll。數據幀:在熊貓中將年份和日期轉換爲日期時間索引

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

我想爲此數據框創建一個索引。索引應該是日期時間索引。這是我在做什麼:

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

但是,這創建一個日期時間索引,它只使用2000年作爲一年。我該如何解決這個問題?

回答

7

您可以使用NumPy datetime64/timedelta64 arithmetic找到所需的日期:

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]') 

由於合成指定的日期的各個部分(如年,月,日,星期,時間等)的日期是一個普遍的問題,在這裏是一個實用的功能,使其更容易:

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']) 

產生

  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

感謝@unutbu! 1970年有什麼特別的嗎?我可以用1900或2000嗎? – user308827

+1

'1970-01-01 00:00:00 UTC'是[Unix Epoch](https://en.wikipedia.org/wiki/Unix_time)。因爲'np.array([0],dtype ='datetime64 [Y]')'返回'array(['1970'],dtype ='datetime64 [Y]')',所以我們必須減去1970. – unutbu

+0

謝謝非常清楚! – user308827

5

你可以使用日期說明符%j來提取一年中的哪一天。因此,結合兩列,轉換一年,並轉換爲日期時間!

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

回報

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]