Thêm np.timedelta64(1, 'Y')
tới một mảng của dtype datetime64[ns]
không làm việc vì một năm không tương ứng với một số cố định của nano giây. Đôi khi một năm là 365 ngày, đôi khi 366 ngày, đôi khi thậm chí còn có thêm một bước nhảy vọt thứ hai. (Lưu ý thêm vài giây nhuận, chẳng hạn như một giây xảy ra vào ngày 2015-06-30 23:59:60, không thể đại diện là NumPy datetime64s.)
Cách dễ nhất tôi biết để thêm một năm vào một số NumPy datetime64[ns]
là để phá vỡ nó thành bộ phận cấu thành, chẳng hạn như năm, tháng và ngày, thực hiện các tính toán trên mảng số nguyên, và sau đó recompose mảng datetime64:
def year(dates):
"Return an array of the years given an array of datetime64s"
return dates.astype('M8[Y]').astype('i8') + 1970
def month(dates):
"Return an array of the months given an array of datetime64s"
return dates.astype('M8[M]').astype('i8') % 12 + 1
def day(dates):
"Return an array of the days of the month given an array of datetime64s"
return (dates - dates.astype('M8[M]'))/np.timedelta64(1, 'D') + 1
def combine64(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)
# break the datetime64 array into constituent parts
years, months, days = [f(dates_np) for f in (year, month, day)]
# recompose the datetime64 array after adding 1 to the years
dates3 = combine64(years+1, months, days)
sản lượng
In [185]: dates3
Out[185]:
array(['1981-01-01', '1981-01-02', '1981-01-03', ..., '2015-12-30',
'2015-12-31', '2016-01-01'], dtype='datetime64[D]')
Mặc dù xuất hiện để được như vậy nhiều mã, nó thực sự nhanh hơn việc thêm DateOff tập hợp 1 năm:
In [206]: %timeit dates + DateOffset(years=1)
1 loops, best of 3: 285 ms per loop
In [207]: %%timeit
.....: years, months, days = [f(dates_np) for f in (year, month, day)]
.....: combine64(years+1, months, days)
.....:
100 loops, best of 3: 2.65 ms per loop
Tất nhiên, pd.tseries.offsets cung cấp một vỏ trang toàn bộ offsets mà không có đối tác dễ dàng khi làm việc với datetime64s NumPy.
Tôi ngạc nhiên trước tốc độ và chi tiết của câu trả lời này! Bởi vì tôi đọc dữ liệu của mình bằng cách sử dụng gấu trúc, tôi thấy dễ dàng hơn khi tiếp tục sử dụng DateOffset của gấu trúc để chuyển đổi ngày trước khi tôi tính toán bằng cách sử dụng gọn gàng. Nhưng tôi đã nghĩ về việc thực hiện một chuyển đổi như bạn đề nghị, vì vậy bây giờ tôi có mã nguồn đó nếu tôi cần nó. Cảm ơn! – questiondude