2016-06-22 2 views
7

Я пишу скрипт, который отображает некоторые данные с датами на оси x (в matplotlib). Мне нужно создать numpy.linspace из этих дат, чтобы впоследствии создать сплайн. Можно ли это сделать?Создание numpy linspace из datetime

Что я пробовал:

import datetime 
import numpy as np 

dates = [ 
    datetime.datetime(2015, 7, 2, 0, 31, 41), 
    datetime.datetime(2015, 7, 2, 1, 35), 
    datetime.datetime(2015, 7, 2, 2, 37, 9), 
    datetime.datetime(2015, 7, 2, 3, 59, 16), 
    datetime.datetime(2015, 7, 2, 5, 2, 23)] 

x = np.linspace(min(dates), max(dates), 500) 

Он бросает эту ошибку:

TypeError: unsupported operand type(s) for *: 'datetime.datetime' and 'float' 

Я также попытался преобразования datetime в np.datetime64, но это не работает, а также:

dates = [ np.datetime64(i) for i in dates ] 
x = np.linspace(min(dates), max(dates), 500) 

Ошибка:

TypeError: ufunc multiply cannot use operands with types dtype('<M8[us]') and dtype('float64') 
+0

Там в 'numpy' обертка' datetime', 'н.п. .datetime64' (я думаю), который может работать. – hpaulj

+0

Уже пробовал, что в вопросе –

ответ

6

Рассматривали ли вы с помощью pandas? Используя подход от this possible duplicate question, вы можете использовать np.linspace следующим образом

import pandas as pd 

start = pd.Timestamp('2015-07-01') 
end = pd.Timestamp('2015-08-01') 
t = np.linspace(start.value, end.value, 100) 
t = pd.to_datetime(t) 

Чтобы получить np.array линейных таймсериях

In [3]: np.asarray(t) 
Out[3]: 
array(['2015-06-30T17:00:00.000000000-0700', 
     '2015-07-01T00:30:54.545454592-0700', 
     '2015-07-01T08:01:49.090909184-0700', 
       ... 
     '2015-07-31T01:58:10.909090816-0700', 
     '2015-07-31T09:29:05.454545408-0700', 
     '2015-07-31T17:00:00.000000000-0700'], dtype='datetime64[ns]') 
5

Насколько я знаю, np.linspace не поддерживает объекты datetime. Но, возможно, мы можем сделать нашу собственную функцию, которая грубо имитирует это:

def date_linspace(start, end, steps): 
    delta = (end - start)/steps 
    increments = range(0, steps) * np.array([delta]*steps) 
    return start + increments 

Это должно дать вам np.array с датами, идущими от start до end в steps шагов (не включая дату окончания, могут быть легко изменены) ,

+0

Спасибо, работает красиво. Я бы дал +1, если бы мог (я слишком много нуба). Не принято (пока), может быть, кто-то придумает что-то встроенное –

+0

delta может быть неточным, а при добавлении неточность приводит к тому, что возвращаемое конечное значение не совпадает с конечным значением, переданным с большим отрывом при работе с небольшие значения времени. – poleguy

0

Последняя ошибка говорит нам, что объекты np.datetime не могут размножаться. Дополнение было определено - вы можете добавить n timesteps к дате и получить другую дату. Но не имеет смысла умножать дату.

In [1238]: x=np.array([1000],dtype='datetime64[s]') 

In [1239]: x 
Out[1239]: array(['1970-01-01T00:16:40'], dtype='datetime64[s]') 

In [1240]: x[0]*3 
... 
TypeError: ufunc multiply cannot use operands with types dtype('<M8[s]') and dtype('int32') 

Таким образом, простой способ сгенерировать диапазон объектов datetime - добавить диапазон временных меток. Вот, например, я использую 10 секунде

In [1241]: x[0]+np.arange(0,60,10) 
Out[1241]: 
array(['1970-01-01T00:16:40', '1970-01-01T00:16:50', '1970-01-01T00:17:00', 
     '1970-01-01T00:17:10', '1970-01-01T00:17:20', '1970-01-01T00:17:30'], dtype='datetime64[s]') 

Ошибка в linspace является результатом его пытаются умножить start на 1., как видно в полный стек ошибок:

In [1244]: np.linspace(x[0],x[-1],10) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-1244-6e50603c0c4e> in <module>() 
----> 1 np.linspace(x[0],x[-1],10) 

/usr/lib/python3/dist-packages/numpy/core/function_base.py in linspace(start, stop, num, endpoint, retstep, dtype) 
    88 
    89  # Convert float/complex array scalars to float, gh-3504 
---> 90  start = start * 1. 
    91  stop = stop * 1. 
    92 

TypeError: ufunc multiply cannot use operands with types dtype('<M8[s]') and dtype('float64') 

Несмотря на комментарий, похоже, что он просто конвертирует ints в float. В любом случае, это не было написано с учетом datetime64 объектов.

user89161's - это путь, если вы хотите использовать синтаксис linspace, иначе вы можете просто добавить приращения выбранного вами размера к дате начала.

arange работы с этими датами:

In [1256]: np.arange(x[0],x[0]+60,10) 
Out[1256]: 
array(['1970-01-01T00:16:40', '1970-01-01T00:16:50', '1970-01-01T00:17:00', 
     '1970-01-01T00:17:10', '1970-01-01T00:17:20', '1970-01-01T00:17:30'], dtype='datetime64[s]') 
Смежные вопросы