Добавление одного месяца к datetime64 с помощью timedelta - PullRequest
0 голосов
/ 20 февраля 2019

Когда я пытаюсь это сделать:

>>> a = numpy.datetime64('1995-12-31')
>>> b = a + pandas.Timedelta(1, unit='M')
>>> print(b)

Я ожидаю увидеть

1996-01-31

, но вместо этого я получаю

1996-01-30 10:29:06.

Есть идеи почему?Большое спасибо.

Ответы [ 4 ]

0 голосов
/ 20 февраля 2019

Краткий способ добавления месяца, оставляя день без изменений, если это возможно, будет усечением до месяцев, добавлением 1 и последующим чтением усеченного:

>>> a = np.datetime64('1995-12-31')                                                              
>>> am = a.astype('M8[M]')                                                    
>>> b = (am + 1) + (a - am)                                                        
>>> b                                                                                            
numpy.datetime64('1996-01-31')                                                                   

Очевидно, что это не сработает, если исходный деньне существует в следующем месяце:

>>> a = np.datetime64('1995-01-31')
>>> am = a.astype('M8[M]')
>>> b = (am + 1) + (a - am)
>>> b
numpy.datetime64('1995-03-03')

Но в любом случае неясно, каким должен быть ответ в этом случае.

Одной из возможностей может быть максимальное достижение в последний день этого месяца:

>>> b = np.minimum((am + 1) + (a - am), (am + 2) - np.timedelta64(1, 'D'))
>>> b
numpy.datetime64('1995-02-28')
0 голосов
/ 20 февраля 2019

Вы можете заменить деталь day, чтобы имитировать требование.

import numpy as np
import pandas as pd
a = np.datetime64('1995-12-31')
b = a + pd.Timedelta(1, unit='M')
print(b.replace(day=pd.to_datetime(a).day))

Используйте .date(), если вас интересует только часть даты

0 голосов
/ 20 февраля 2019

Существует некоторая двусмысленность в добавлении «месяца» ко времени, так как месяцы различаются по длине.

Создайте дату:

In [247]: a = np.array('1995-12-31','datetime64[D]')                            
In [248]: a                                                                     
Out[248]: array('1995-12-31', dtype='datetime64[D]')

добавление дней к этому работает нормально:

In [249]: a + np.array(31, 'timedelta64[D]')                                    
Out[249]: numpy.datetime64('1996-01-31')

При добавлении месяца возникает ошибка:

In [250]: a + np.array(1, 'timedelta64[M]')                                     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-250-a331f724d7e7> in <module>
----> 1 a + np.array(1, 'timedelta64[M]')

TypeError: Cannot get a common metadata divisor for NumPy datetime metadata [D] and [M] because they have incompatible nonlinear base time units

Мы можем разыграть a как месяц - тогда это работает:

In [251]: a.astype('datetime64[M]')                                             
Out[251]: array('1995-12', dtype='datetime64[M]')
In [252]: a.astype('datetime64[M]') + np.array(1, 'timedelta64[M]')             
Out[252]: numpy.datetime64('1996-01')

Изменить месяцв соответствующем datetime объекте может быть самый чистый способ работы с этим:

In [254]: b = a.item()                                                          
In [255]: b                                                                     
Out[255]: datetime.date(1995, 12, 31)

Я недостаточно поработал с datetime объектами, чтобы внести изменения, не глядя на его документы.

0 голосов
/ 20 февраля 2019

Дельта времени одного месяца - это длина года, деленная на 12.

Вам необходимо проверить свою дату и добавить соответствующее количество дней.Также можно увеличить номер месяца (при необходимости перенести на следующий год) и оставить номер дня без изменений.

...