#python #list #numpy
#питон #Список #numpy
Вопрос:
У меня есть список дат. Я хочу преобразовать это в список, в котором отображаются промежутки времени между датами. Следующий код работает нормально, однако, если я посмотрю на него, он кажется излишним. Сначала я преобразую список в массив numpy, затем создаю массив dureation и преобразую его обратно в список секунд. Я сталкиваюсь с этим много раз, поэтому было бы здорово, если бы кто-нибудь сказал мне, каким наиболее эффективным способом было бы это сделать.
import datetime;
from numpy import *
times = [datetime.datetime(2014, 6, 23, 18, 56, 30),
datetime.datetime(2014, 6, 23, 18, 57),
datetime.datetime(2014, 6, 23, 18, 57, 30),
datetime.datetime(2014, 6, 23, 18, 58),
datetime.datetime(2014, 6, 23, 18, 58, 30),
datetime.datetime(2014, 6, 23, 18, 59),
datetime.datetime(2014, 6, 23, 18, 59, 30)]
seconds = array(times)
start = times[0]
duration = seconds - start
secs = [];
for item in duration:
secs.append(item.seconds);
# result: secs = [0, 30, 60, 90, 120, 150, 180]
Ответ №1:
Вы можете выполнять вычитание datetime
объектов напрямую:
>>> [(a - times[0]).total_seconds() for a in times]
[0, 30, 60, 90, 120, 150, 180]
Когда вы вычитаете два datetime.datetime
объекта, вы получаете datetime.timedelta
обратно объект, который представляет промежуток времени между ними datetimes
. Таким образом, вы можете просто выполнить итерацию по списку, вычесть текущее время из первого раза и использовать total_seconds()
метод из timedelta
объекта, который он возвращает, чтобы получить разницу в секундах.
Ответ №2:
Что-то вроде этого будет работать (не требуется numpy):
times = [datetime.datetime(2014, 6, 23, 18, 56, 30),
datetime.datetime(2014, 6, 23, 18, 57),
datetime.datetime(2014, 6, 23, 18, 57, 30),
datetime.datetime(2014, 6, 23, 18, 58),
datetime.datetime(2014, 6, 23, 18, 58, 30),
datetime.datetime(2014, 6, 23, 18, 59),
datetime.datetime(2014, 6, 23, 18, 59, 30)]
start = times[0]
output = [ (t - start).seconds for t in times]
print output
# [0, 30, 60, 90, 120, 150, 180]
Редактировать: я вижу, что меня избили! Хорошая работа: D
Ответ №3:
С помощью строки duration = seconds - start
вы создаете список временных дельт в numpy:
>>> duration
[datetime.timedelta(0) datetime.timedelta(0, 30) datetime.timedelta(0, 60) datetime.timedelta(0, 90) datetime.timedelta(0, 120) datetime.timedelta(0, 150) datetime.timedelta(0, 180)]
Таким образом, вы можете создать то, что хотите, непосредственно с помощью numpy.vectorize, чтобы создать новый массив, который отделяет общее количество секунд от duration
массива.
Если вы делаете это только один раз, вы можете использовать vectorize как функцию удаления, подобную карте:
>>> vectorize(lambda td: td.total_seconds())(duration)
[ 0. 30. 60. 90. 120. 150. 180.]
Или сохраните его, чтобы использовать несколько раз:
>>> v=vectorize(lambda td: td.total_seconds())
>>> v(duration), v(duration*2)
[ 0. 30. 60. 90. 120. 150. 180.] [ 0. 60. 120. 180. 240. 300. 360.]
Преимущество заключается в том, что если вы работаете в numpy, это сохраняет данные в numpy — нет обратного перехода к Python, поскольку это приведет к пониманию списка.
Ответ №4:
numpy.diff
должно работать: http://docs.scipy.org/doc/numpy/reference/generated/numpy.diff.html
Это должно быть быстрее, как только ваши списки дат и времени станут большими (не уверен, почему вы используете numpy для вышеупомянутого). Вероятно, вы могли бы получить еще большую производительность, если переключитесь на типы numpy datetime.
>>> times = numpy.array(times)
>>> diffs =numpy.diff(times)
>>> diffs
array([datetime.timedelta(0, 30), datetime.timedelta(0, 30),
datetime.timedelta(0, 30), datetime.timedelta(0, 30),
datetime.timedelta(0, 30), datetime.timedelta(0, 30)], dtype=object)
Если вам нужны исходные числа секунд, вы можете получить их с помощью timedelta.total_seconds()
метода:
seconds = [x.total_seconds() for x in diffs]
Редактировать:
Если предполагается, что все дельты относятся к первому значению даты и времени, вы можете просто сделать:
seconds = [x.total_seconds() for x in times - times[0]]
В этом нет необходимости diff
…
Комментарии:
1. Я думаю, что, глядя на вывод OP, им понадобится что-то вроде:
np.cumsum([0] [x.total_seconds() for x in diffs])