2015-12-14 24 views
6

Tôi có các foll. dataframe:Chuyển đổi năm và ngày trong năm thành chỉ số ngày giờ trong gấu trúc

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

Tôi muốn tạo chỉ mục cho khung dữ liệu này. Chỉ mục phải là chỉ mục datetime. Dưới đây là những gì tôi đang thực hiện:

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

Tuy nhiên, điều này tạo chỉ mục thời gian sử dụng năm 2000 là năm. Lam sao tôi co thể sửa no?

Trả lời

7

Bạn có thể sử dụng NumPy datetime64/timedelta64 arithmetic để tìm ra ngày mong muốn:

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

Kể từ khi sáng tác ngày cho các phần khác nhau của ngày (ví dụ năm, tháng, ngày, tuần, giờ, vv) là một vấn đề phổ biến, đây là một chức năng tiện ích để làm cho nó dễ dàng hơn:

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

mang

  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

nhờ @unutbu! có điều gì đặc biệt vào năm 1970 không? tôi có thể sử dụng 1900 hoặc 2000 không? – user308827

+1

'1970-01-01 00:00:00 UTC' là [Unix Epoch] (https://en.wikipedia.org/wiki/Unix_time). Vì 'np.array ([0], dtype = 'datetime64 [Y]')' trả về 'mảng (['1970'], dtype = 'datetime64 [Y]')', chúng ta phải trừ năm 1970. – unutbu

+0

cảm ơn đây là rất rõ ràng! – user308827

5

Bạn có thể sử dụng số ngày tháng %j để trích xuất ngày trong năm. Vì vậy, kết hợp hai cột, thay đổi năm và chuyển đổi thành datetime!

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

lợi nhuận

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] 
Các vấn đề liên quan