Почему numpy массивы не могут конвертировать из datetime в np.datetime64 неявно?

Скажем, у меня есть datetime:

given_time = datetime(2013, 10, 8, 0, 0, 33, 945109,
                      tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=60, 
                                                             name=None))

Я хотел бы преобразовать его в np.datetime64:

np.datetime64(given_time)
> numpy.datetime64('2013-10-08T00:00:33.945109+0100')

Это хорошо работает. Однако, если у меня есть массив given_time:

given_times = np.array([given_time]*3) # dtype is object

Оба given_times.astype('datetime64') и given_times = np.array([given_time] * 3, dtype=np.datetime64) запускают TypeError: Cannot cast datetime.datetime object from metadata [us] to [D] according to the rule 'same_kind'

Итак, я должен указать единицу:

given_times.astype('datetime64[us]')
# or
given_times = np.array([given_time]*3, dtype='datetime64[us]')

Мой вопрос: зачем мне здесь указывать блок? Он не требует единицы в конструкторе np.datatime64.

Ответы

Ответ 1

Я знаю, что это старый вопрос, но я постараюсь ответить, если кто-то еще встретит это.

  • Начиная с 1.11, numpy не пытается автоматически конвертировать итерации объектов date/datetime в массивы datetime64, это довольно ясно из this excerpt в тестовом наборе:
# at the moment, we don't automatically convert these to datetime64

dt = datetime.date(1970, 1, 1)
arr = np.array([dt])
assert_equal(arr.dtype, np.dtype('O'))

dt = datetime.datetime(1970, 1, 1, 12, 30, 40)     
arr = np.array([dt])
assert_equal(arr.dtype, np.dtype('O'))

В идеале numpy будет означать, что datetime64 с правильными единицами можно использовать; см. этот вопрос.

  1. При построении datetime64 из скаляра единица, установленная для M8[D] для объектов даты и M8[us] для объектов datetime (соответствующий тест).

  2. Когда вы указываете dtype='datetime64' или, аналогично, dtype='M8', единицы устанавливаются в "generic", который позже разрешается до M8[D] (хотя было бы логично разрешить его M8[D], см. этот вопрос):

>>> np.datetime_data(np.dtype('datetime64'))
('generic', 1)
>>> np.datetime_data(np.dtype('M8'))
('generic', 1)
>>> np.datetime_data(np.dtype('M8[D]'))
('D', 1)
>>> np.datetime_data(np.dtype('M8[us]'))
('us', 1)
  1. given_times.astype('datetime64') больше не вызывает исключение - это было fixed в 1.11.

  2. Начиная с 1.11, объекты datetime64 являются часовыми наивными, поэтому передача объекта datetime с помощью tzinfo, установленного как в предоставленном пример вызовет предупреждение об отказе.