Вы обычно размещаете эти типы констант в объекте Configuration
(который имеет геттеры и сеттеры) в контексте сервлета и обращаются к ним с помощью ${applicationScope.config.url}
Чтобы преобразовать numpy.datetime64
в объект datetime, который представляет время в UTC на numpy-1.8
:
>>> from datetime import datetime
>>> import numpy as np
>>> dt = datetime.utcnow()
>>> dt
datetime.datetime(2012, 12, 4, 19, 51, 25, 362455)
>>> dt64 = np.datetime64(dt)
>>> ts = (dt64 - np.datetime64('1970-01-01T00:00:00Z')) / np.timedelta64(1, 's')
>>> ts
1354650685.3624549
>>> datetime.utcfromtimestamp(ts)
datetime.datetime(2012, 12, 4, 19, 51, 25, 362455)
>>> np.__version__
'1.8.0.dev-7b75899'
В приведенном выше примере предполагается, что наивный объект datetime интерпретируется np.datetime64
как время в UTC .
Чтобы преобразовать datetime в np.datetime64 и назад (numpy-1.6
):
>>> np.datetime64(datetime.utcnow()).astype(datetime)
datetime.datetime(2012, 12, 4, 13, 34, 52, 827542)
Он работает как на одном объекте np.datetime64, так и на массиве numpy из np.datetime64.
Подумайте о np.datetime64 так же, как и о np.int8, np.int16 и т. д. и примените те же методы для преобразования между объектами Python, такими как int, datetime и соответствующий numpy объекты.
Ваш «неприятный пример» работает правильно:
>>> from datetime import datetime
>>> import numpy
>>> numpy.datetime64('2002-06-28T01:00:00.000000000+0100').astype(datetime)
datetime.datetime(2002, 6, 28, 0, 0)
>>> numpy.__version__
'1.6.2' # current version available via pip install numpy
Я могу воспроизвести значение long
на numpy-1.8.0
, установленное как:
pip install git+https://github.com/numpy/numpy.git#egg=numpy-dev
Тот же пример:
>>> from datetime import datetime
>>> import numpy
>>> numpy.datetime64('2002-06-28T01:00:00.000000000+0100').astype(datetime)
1025222400000000000L
>>> numpy.__version__
'1.8.0.dev-7b75899'
Он возвращает long
, потому что для numpy.datetime64
тип .astype(datetime)
эквивалентен .astype(object)
, который возвращает целое число Python (long
) на numpy-1.8
.
Чтобы получить объект datetime, вы могли бы:
>>> dt64.dtype
dtype('<M8[ns]')
>>> ns = 1e-9 # number of seconds in a nanosecond
>>> datetime.utcfromtimestamp(dt64.astype(int) * ns)
datetime.datetime(2002, 6, 28, 0, 0)
Чтобы получить datetime64, который использует секунды напрямую:
>>> dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100', 's')
>>> dt64.dtype
dtype('<M8[s]')
>>> datetime.utcfromtimestamp(dt64.astype(int))
datetime.datetime(2002, 6, 28, 0, 0)
Документы numpy говорят, что API-интерфейс datetime является экспериментальным и может меняться в будущих версиях numpy.
Один вариант - использовать str
, а затем to_datetime
(или аналогичный):
In [11]: str(dt64)
Out[11]: '2012-05-01T01:00:00.000000+0100'
In [12]: pd.to_datetime(str(dt64))
Out[12]: datetime.datetime(2012, 5, 1, 1, 0, tzinfo=tzoffset(None, 3600))
Примечание: он не равен dt
, потому что он становится "offset-aware" :
In [13]: pd.to_datetime(str(dt64)).replace(tzinfo=None)
Out[13]: datetime.datetime(2012, 5, 1, 1, 0)
Это кажется неэлегантным.
.
Обновление: это может касаться «неприятный пример»:
In [21]: dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')
In [22]: pd.to_datetime(str(dt64)).replace(tzinfo=None)
Out[22]: datetime.datetime(2002, 6, 28, 1, 0)
import numpy as np
import pandas as pd
def np64toDate(np64):
return pd.to_datetime(str(np64)).replace(tzinfo=None).to_datetime()
использовать эту функцию, чтобы получить собственный объект datetime для pythons
replace() got an unexpected keyword argument 'tzinfo'
– ogogmad
4 October 2016 в 11:23
>>> dt64.tolist()
datetime.datetime(2012, 5, 1, 0, 0)
Для DatetimeIndex
, tolist
возвращает список объектов datetime
. Для одного объекта datetime64
он возвращает один объект datetime
.
.item()
, который намного более ясен (и никто не может прийти и начать утверждать, что он должен возвращать список).
– seberg
4 December 2012 в 16:03
dt64 = numpy.datetime64('2002-06-28T01:00:00.000000000+0100')
, который дает длинный (1025222400000000000L
) (!)
– Andy Hayden
4 December 2012 в 19:46
.item()
(предложенный @seberg), .tolist()
зависит от того, какие единицы datetime64 использует, например, D
производит datetime.date()
, us
(микросекунды), производит datetime.datetime()
, ns
(наносекунды) long
. И единицы изменяются в зависимости от входных значений, например, numpy.datetime64('2012-05-01')
использует 'D'
, numpy.datetime64('2012-05-01T00:00:00.000')
использует ms
, numpy.datetime64('2012-05-01T00:00:00.000000000')
использует ns
. Вы можете открыть проблему , если вы считаете ее запутанной.
– jfs
4 December 2012 в 22:51
Если вы хотите преобразовать целую серию pandas datetimes в регулярные datetimes python, вы также можете использовать .to_pydatetime()
.
pd.date_range('20110101','20110102',freq='H').to_pydatetime()
> [datetime.datetime(2011, 1, 1, 0, 0) datetime.datetime(2011, 1, 1, 1, 0)
datetime.datetime(2011, 1, 1, 2, 0) datetime.datetime(2011, 1, 1, 3, 0)
....
Он также поддерживает часовые пояса:
pd.date_range('20110101','20110102',freq='H').tz_localize('UTC').tz_convert('Australia/Sydney').to_pydatetime()
[ datetime.datetime(2011, 1, 1, 11, 0, tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
datetime.datetime(2011, 1, 1, 12, 0, tzinfo=<DstTzInfo 'Australia/Sydney' EST+11:00:00 DST>)
....
Некоторые решения работают хорошо для меня, но numpy будет обесценивать некоторые параметры. Решение, которое лучше работает для меня, - это прочитать дату как дата и время pandas и явно исключить год, месяц и день объекта pandas. Следующий код работает для наиболее распространенной ситуации.
def format_dates(dates):
dt = pd.to_datetime(dates)
try: return [datetime.date(x.year, x.month, x.day) for x in dt]
except TypeError: return datetime.date(dt.year, dt.month, dt.day)
Это сообщение было в течение 4 лет, и я все еще боролся с этой проблемой конверсии - так что проблема по-прежнему активна в 2017 году в некотором смысле. Я был несколько шокирован тем, что документация numpy не дает простого алгоритма преобразования, но это уже другая история.
Я столкнулся с другим способом преобразования, который включает только модули numpy
и datetime
, он не требует импортировать панды, которые, как мне кажется, содержат много кода для импорта для такого простого преобразования. Я заметил, что datetime64.astype(datetime.datetime)
вернет объект datetime.datetime
, если исходный datetime64
находится в микросекундах, в то время как другие единицы возвращают целую метку времени. Я использую модуль xarray
для ввода / вывода данных из файлов Netcdf, который использует datetime64
в наносекундах, что делает переход неудачным, если вы не впервые конвертируете в микросекунды. Вот пример кода преобразования,
import numpy as np
import datetime
def convert_datetime64_to_datetime( usert: np.datetime64 )->datetime.datetime:
t = np.datetime64( usert, 'us').astype(datetime.datetime)
return t
. Его единственный протестированный на моей машине, который представляет собой Python 3.6 с недавним дистрибутивом Anaconda 2017 года. Я только посмотрел на скалярное преобразование и не проверил преобразования на основе массива, хотя я предполагаю, что это будет хорошо. Я также не смотрел исходный код numpy datetime64, чтобы убедиться, что операция имеет смысл или нет.
Я вернусь к этому ответу больше раз, чем могу подсчитать, поэтому решил собрать небольшой класс, который преобразует значение Numpy datetime64
в значение Python datetime
. Я надеюсь, что это поможет другим.
from datetime import datetime
import pandas as pd
class NumpyConverter(object):
@classmethod
def to_datetime(cls, dt64, tzinfo=None):
"""
Converts a Numpy datetime64 to a Python datetime.
:param dt64: A Numpy datetime64 variable
:type dt64: numpy.datetime64
:param tzinfo: The timezone the date / time value is in
:type tzinfo: pytz.timezone
:return: A Python datetime variable
:rtype: datetime
"""
ts = pd.to_datetime(dt64)
if tzinfo is not None:
return datetime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second, tzinfo=tzinfo)
return datetime(ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second)
Я собираюсь держать это в сумке для инструмента, что-то подсказывает мне, что мне понадобится еще раз.
Вы можете просто использовать конструктор pd.Timestamp. Следующая диаграмма может быть полезна для этого и связанных вопросов.
[/g0]
pd.to_datetime
преобразует все в pd.Timestamp
. Объект pd.Timestamp
имеет метод to_pydatetime
, чтобы вернуться к объекту datetime.datetime
и to_datetime64
для преобразования в np.datetime64
.
– Ted Petrou
1 July 2017 в 14:19
Я думаю, что может быть более консолидированное усилие в ответ на лучшее объяснение взаимосвязи между модулем datetime Python, datetime64 / timedelta64 numpy и объектами Timestamp / Timedelta pandas.
Стандартная библиотека datetime имеет четыре основных объекта
>>> import datetime
>>> datetime.time(hour=4, minute=3, second=10, microsecond=7199)
datetime.time(4, 3, 10, 7199)
>>> datetime.date(year=2017, month=10, day=24)
datetime.date(2017, 10, 24)
>>> datetime.datetime(year=2017, month=10, day=24, hour=4, minute=3, second=10, microsecond=7199)
datetime.datetime(2017, 10, 24, 4, 3, 10, 7199)
>>> datetime.timedelta(days=3, minutes = 55)
datetime.timedelta(3, 3300)
>>> # add timedelta to datetime
>>> datetime.timedelta(days=3, minutes = 55) + \
datetime.datetime(year=2017, month=10, day=24, hour=4, minute=3, second=10, microsecond=7199)
datetime.datetime(2017, 10, 27, 4, 58, 10, 7199)
NumPy не имеет отдельных объектов даты и времени, а всего лишь один объект datetime64 для представления одного момента времени. Объект datetime модуля datetime имеет точность в микросекундах (одна миллионная часть секунды). Объект datetime64 NumPy позволяет задавать свою точность от часов до атсосекунд (10 ^ -18). Конструктор более гибкий и может принимать различные входы.
Передавать целое число со строкой для единиц. Просмотреть все единицы здесь . Он преобразуется во многие единицы после эпохи UNIX: 1 января 1970 г.
>>> np.datetime64(5, 'ns')
numpy.datetime64('1970-01-01T00:00:00.000000005')
>>> np.datetime64(1508887504, 's')
numpy.datetime64('2017-10-24T23:25:04')
Вы также можете использовать строки, если они находятся в формате ISO 8601.
>>> np.datetime64('2017-10-24')
numpy.datetime64('2017-10-24')
Timedeltas имеют единственную единицу
>>> np.timedelta64(5, 'D') # 5 days
>>> np.timedelta64(10, 'h') 10 hours
Можно также создать их путем вычитания двух объектов datetime64
>>> np.datetime64('2017-10-24T05:30:45.67') - np.datetime64('2017-10-22T12:35:40.123')
numpy.timedelta64(147305547,'ms')
Временная метка pandas - это момент времени, очень похожий на дату и время, но с гораздо большей функциональностью. Вы можете построить их с помощью pd.Timestamp
или pd.to_datetime
.
>>> pd.Timestamp(1239.1238934) #defautls to nanoseconds
Timestamp('1970-01-01 00:00:00.000001239')
>>> pd.Timestamp(1239.1238934, unit='D') # change units
Timestamp('1973-05-24 02:58:24.355200')
>>> pd.Timestamp('2017-10-24 05') # partial strings work
Timestamp('2017-10-24 05:00:00')
pd.to_datetime
работает очень аналогично (с несколькими дополнительными параметрами) и может преобразовать список строк в отметки времени.
>>> pd.to_datetime('2017-10-24 05')
Timestamp('2017-10-24 05:00:00')
>>> pd.to_datetime(['2017-1-1', '2017-1-2'])
DatetimeIndex(['2017-01-01', '2017-01-02'], dtype='datetime64[ns]', freq=None)
>>> dt = datetime.datetime(year=2017, month=10, day=24, hour=4,
minute=3, second=10, microsecond=7199)
>>> np.datetime64(dt)
numpy.datetime64('2017-10-24T04:03:10.007199')
>>> pd.Timestamp(dt) # or pd.to_datetime(dt)
Timestamp('2017-10-24 04:03:10.007199')
>>> dt64 = np.datetime64('2017-10-24 05:34:20.123456')
>>> unix_epoch = np.datetime64(0, 's')
>>> one_second = np.timedelta64(1, 's')
>>> seconds_since_epoch = (dt64 - unix_epoch) / one_second
>>> seconds_since_epoch
1508823260.123456
>>> datetime.datetime.utcfromtimestamp(seconds_since_epoch)
>>> datetime.datetime(2017, 10, 24, 5, 34, 20, 123456)
Преобразование в метку времени
>>> pd.Timestamp(dt64)
Timestamp('2017-10-24 05:34:20.123456')
Это довольно просто, поскольку временные метки pandas очень мощные
>>> ts = pd.Timestamp('2017-10-24 04:24:33.654321')
>>> ts.to_pydatetime() # Python's datetime
datetime.datetime(2017, 10, 24, 4, 24, 33, 654321)
>>> ts.to_datetime64()
numpy.datetime64('2017-10-24T04:24:33.654321000')
Добро пожаловать в ад.
Вы можете просто передать объект datetime64 в pandas.Timestamp
:
In [16]: Timestamp(numpy.datetime64('2012-05-01T01:00:00.000000'))
Out[16]: <Timestamp: 2012-05-01 01:00:00>
Я заметил, что это не работает правильно, хотя в NumPy 1.6. 1:
numpy.datetime64('2012-05-01T01:00:00.000000+0100')
Также можно использовать pandas.to_datetime
(это отключено от версии dev, не проверено v0.9.1):
In [24]: pandas.to_datetime('2012-05-01T01:00:00.000000+0100')
Out[24]: datetime.datetime(2012, 5, 1, 1, 0, tzinfo=tzoffset(None, 3600))
issubclass(pd.Timestamp, datetime)
- True
. А сам класс Timestamp
имеет метод to_datetime()
.
– jfs
20 April 2015 в 23:21
pd.to_datetime('2012-05-01T01:00:00.000000+0100')
возвращает Timestamp('2012-05-01 00:00:00')
по крайней мере в pandas 0.17.1
.
– Anton Protopopov
21 January 2016 в 11:15
действительно, все эти типы datetime могут быть трудными и потенциально проблематичными (необходимо внимательно следить за информацией о часовом поясе). вот что я сделал, хотя я признаю, что меня беспокоит, что по крайней мере часть его «не по дизайну». Кроме того, это может быть сделано немного более компактным по мере необходимости. начиная с numpy.datetime64 dt_a:
dt_a
blockquote>numpy.datetime64 ('2015-04-24T23: 11: 26.270000-0700')
dt_a1 = dt_a.tolist () # дает объект datetime в UTC, но без tzinfo
dt_a1
blockquote>datetime.datetime (2015) , [4], [4] [+] ], tzinfo = pytz.timezone ('UTC'))
blockquote>... и, конечно, это может быть сжато в одну строку по мере необходимости.
type(dt64)
.dt64.astype(datetime) == datetime.utcfromtimestamp(dt64.astype(int)*1e-6)
– jfs 4 December 2012 в 19:59type(dt64)
-numpy.datetime64
, аdt64.astype(datetime)
- это тот же самый длинный int ...: s – Andy Hayden 4 December 2012 в 20:10numpy.__version__
- & gt;'1.6.1'
– jfs 4 December 2012 в 20:11