【问题标题】:How to calculate average of seconds & milliseconds in Python?如何在 Python 中计算秒和毫秒的平均值?
【发布时间】:2018-06-01 21:30:21
【问题描述】:

我的数据格式为 HH:MM:SS.milliseconds。如何在 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

【问题讨论】:

  • 首先,您的格式有微秒,而不是毫秒(即使最后三位数字始终为 0,所以它们也可能是毫秒)。
  • Anyway:将它们转换为 datetime.timedelta 对象,或整数微秒或毫秒,或浮点秒,或任何其他可以进行基本算术的类型,然后您可以按照与您相同的方式对它们进行平均平均其他任何东西:使用statistics.mean,或者只是sum(times) / len(times)
  • 你试过什么?提示:将所有内容转换为纯毫秒表示
  • 另外,你为什么用 -3.x 和 -2.7 标记这个?你真的需要在这两种情况下都有效的代码吗?
  • @abarnert:我会尝试你的建议。我是python的初学者。不,我不想只在 2.7 中使用 3.x 中的代码。我错误地标记了 3.x。感谢您的回复。

标签: python python-2.7 timedelta


【解决方案1】:

我不知道您的数据大小,也不知道您是否需要内置解决方案。

但是,一种简单的解决方案是使用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_timedeltamean 就可以了

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

可能/可能不会矫枉过正,但它确实可读且简单。

【讨论】:

  • RafaelC:谢谢。我们可以在列表中做类似的事情吗?
  • 如果你想自己实现,我推荐@abarnert 的回答:)
  • @A.S 这段代码已经有一个列表,如果你需要结果是一个列表而不是Series,你可以直接调用list
【解决方案2】:

第一步是将所有这些时间戳解析为可以进行算术运算的东西。这可以是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

【讨论】:

    【解决方案3】:

    看起来输入由字符串组成。这些应该转换为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)
    

    【讨论】:

      【解决方案4】:

      我假设每个都是一个字符串,您可以在 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))
      

      【讨论】:

        【解决方案5】:

        这是使用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(0) 参数的timedelta 对象,这个技巧courtesy of @JochenRitzel

        【讨论】:

          猜你喜欢
          • 2021-12-16
          • 2022-10-05
          • 2023-02-21
          • 2010-12-26
          • 2015-09-10
          • 2023-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多