Как рассчитать среднее значение секунд и миллисекунд в Python? - PullRequest
0 голосов
/ 02 июня 2018

Мои данные в формате ЧЧ: ММ: СС.миллисекунды.Как рассчитать среднее значение таких данных в Python?Мне нужно среднее в виде миллисекунд.Я просмотрел несколько похожих сообщений, но они не отвечают на мой вопрос.

My data =  0:00:00.618000
           0:00:00.593000
           0:00:00.569000
           0:00:00.572000
           0:00:00.636000
           0:00:01
           0:00:01
           0:00:00.546000
           0:00:00.400000

Ответы [ 5 ]

0 голосов
/ 02 июня 2018

Вот один подход, использующий datetime.timedelta.Сложная задача - преобразовать строки в timedelta объекты.Распаковка последовательностей делает это проще и эффективнее в реализации.

from datetime import timedelta

data = ['0:00:00.618000', '0:00:00.593000', '0:00:00.569000',
        '0:00:00.572000', '0:00:00.636000', '0:00:01',
        '0:00:01', '0:00:00.546000', '0:00:00.400000']

def converter(x):
    if '.' not in x:
        x += '.000000'
    hrs, mins, secs, millis = map(int, x[:-3].replace('.', ':').split(':'))
    return timedelta(hours=hrs, minutes=mins, seconds=secs, milliseconds=millis)

res = sum(map(converter, data), timedelta(0)) / len(data)

print(res)

0:00:00.659333

Обратите внимание, что sum, похоже, работает только с timedelta объектами с добавленным аргументом timedelta(0), этот трюк любезно предоставлен @JochenRitzel.

0 голосов
/ 02 июня 2018

Похоже, что вход состоит из строк.Они должны быть преобразованы в datetime.datetime объекты.Для этого используйте datetime.datetime.strptime.

После этого среднее значение чего-либо вычисляется как sum(values) / len(values), но, к сожалению, вы не можете суммировать даты.Вы можете суммировать разницу дат, поэтому вам нужно будет сделать несколько конверсий

Например:

dates = [datetime.datetime(1951, 1, 5),
         datetime.datetime(1951, 1, 7),
         datetime.datetime(1951, 1, 7)]

base_datetime = datetime.datetime.now()  # really, anything

relative_dates = [d-base_datetime for d in dates]

average_relative_datetime = sum(relative_dates, datetime.timedelta()) / len(relative_dates)

result = base_datetime + average_relative_datetime  # datetime.datetime(1951, 1, 6, 8, 0)
0 голосов
/ 02 июня 2018

Я предполагаю, что каждый из них является строкой, вы можете сделать следующее, не используя библиотек в Python 2 и 3

def mean(numbers):
    return float(sum(numbers)) / max(len(numbers), 1)

def timestamp_to_millis(timestamp):
    hour, min, sec = map(float, timestamp.split(':'))
    mills = (((hour * 60 + min) * 60) + sec) * 1000
    return millis


my_data = # [ timestamps ... ]
my_mean = mean(map(timestamp_to_millis, my_data))
0 голосов
/ 02 июня 2018

Первый шаг - разобрать все эти временные метки во что-то, над чем вы можете выполнять арифметику.Это могут быть timedelta объекты или целые микросекунды (или миллисекунды, поскольку у вас все время имеют 0 микро), или числа с плавающей запятой, или любой другой разумный тип.

Например, если предположитьэти входные данные представляют собой одну большую строку:

ts = []
for h, m, s, u in re.findall(r'(\d+):(\d+):(\d+)(?:\.(\d+))?', bigstring):
    h, m, s = int(h), int(m), int(s)
    u = int(u) if u else 0
    ts.append(datetime.timedelta(hours=h, minutes=m, seconds=s, microseconds=u))

Если это список строк или файловый объект и т. д., просто измените его, чтобы выполнить итерацию, и выполните re.search для каждой из них, вместо итерации re.findall.

Тогда мы можем усреднить их так же, как и любые другие значения:

sum(ts, datetime.timedelta()) / len(ts)

Поскольку я использовал timedelta значений, результат будет таким:

datetime.timedelta(0, 0, 659333)

… или, если вы print это:

0:00:00.659333

… или, если хотите, скажем, за несколько секунд, просто вызовите его метод total_seconds():

0.659333
0 голосов
/ 02 июня 2018

Я не знаю, какой у вас размер данных, или вам требуется встроенное решение, или нет.

Однако, одно простое решение предполагает использование pandas.Если у вас есть

mydata = ["0:00:00.618000",
          "0:00:00.593000",
          "0:00:00.569000",
          "0:00:00.572000",
          "0:00:00.636000",
          "0:00:01",
          "0:00:01",
          "0:00:00.546000",
          "0:00:00.400000"]

Вы можете использовать pd.to_timedelta и mean и просто сделать

pd.Series(pd.to_timedelta(mydata)).mean()

Может быть / не может быть излишним, но это действительно читабельно и просто.

...