python - 从日期时间获取 SQLite 中的平均时间

标签 python sql sqlite time average

我在 SQLite 中的时间格式为“2012-02-21 00:00:00.000000”,并且希望将一天中的时间一起平均。日期并不重要——重要的是时间。因此,例如,如果数据是:

'2012-02-18 20:00:00.000000' 
'2012-02-19 21:00:00.000000' 
'2012-02-20 22:00:00.000000' 
'2012-02-21 23:00:00.000000' 

20、21、22、23 的平均值应为 21.5 或 21:30(在美国为晚上 9:30)。

Q1) 有没有最好的方法在 SQLite 的 SELECT 查询中执行此操作?

但更困难的是:如果一个或多个日期时间跨越午夜怎么办?他们肯定会出现在我的数据集中。示例:

'2012-02-18 22:00:00.000000'
'2012-02-19 23:00:00.000000' 
'2012-02-21 01:00:00.000000'

现在平均值似乎应该是 (22 + 23 + 1)/3 = 15.33 或 15:20 (3:20pm)。但这会歪曲数据,因为这些事件都发生在晚上,从 22:00 到 01:00(晚上 10 点到凌晨 1 点)。实际上,更好的方法是将它们平均起来,例如 (22 + 23 + 25)/3 = 23.33 或 23:20 (11:20pm)。 average of times illustration

Q2)我应该对 SELECT 查询做些什么来考虑到这一点,还是我必须用 Python 编写代码?

最佳答案

你真正想要计算什么?

  • 日期时间(或 1 天内的时间)通常表示为实数
  • 24 小时制的时间坐标是复数,但是
  • 时间的实数表示的平均值会给你可疑的结果......

我不知道您想如何处理 [1:0013:00] 等边缘情况,但让我们考虑以下示例: [01:3006:3013:2015:3016:1516:4517:10] enter image description here

我建议在Python中实现这个算法:

  1. 将时间转换为复数 - 例如计算它们在半径 = 1 的圆上的坐标
  2. 使用向量加法计算平均值
  3. 将结果向量角度转换为分钟 + 计算该结果的相关性(例如 [1:00, 13:00] 的平均值的相关性应该由于舍入误差,无论计算出什么角度,都为 0)
import math
def complex_average(minutes):
    # first convert the times from minutes (0:00 - 23:59) to radians
    # so we get list for quasi polar coordinates (1, radians)
    # (no point in rotating/flipping to get real polar coordinates)
    # 180° = 1/2 day = 24*60/2 minutes
    radians = [t*math.pi/(24*60/2) for t in minutes]
    xs = []
    ys = []
    for r in radians:
        # convert polar coordinates (1, r) to cartesian (x, y)
        # the vectors start at (0, 0) and end in (x, y)
        x, y = (math.cos(r), math.sin(r))
        xs.append(x)
        ys.append(y)

    # result vector = vector addition
    sum_x, sum_y = (sum(ys), sum(xs))

    # convert result vector coordinates to radians, then to minutes
    # note the cumulative ROUNDING ERRORS, however
    result_radians = math.atan2(sum_x, sum_y)
    result_minutes = int(result_radians / math.pi * (24*60/2))
    if result_minutes < 0:
        result_minutes += 24*60

    # relevance = magnitude of the result vector / number of data points
    # (<0.0001 means that all vectors cancel each other, e.g. [1:00, 13:00]
    #  => result_minutes would be random due to rounding error)
    # FYI: standart_deviation = 6*60 - 6*60*relevance
    relevance = round(math.sqrt(sum_x**2 + sum_y**2) / len(minutes), 4)

    return result_minutes, relevance

并像这样测试它:

# let's say the select returned a bunch of integers in minutes representing times
selected_times = [90, 390, 800, 930, 975, 1005, 1030]
# or create other test data:
#selected_times = [hour*60 for hour in [23,22,1]]

complex_avg_minutes, relevance = complex_average(selected_times)
print("complex_avg_minutes = {:02}:{:02}".format(complex_avg_minutes//60,
                                                 complex_avg_minutes%60),
      "(relevance = {}%)".format(int(round(relevance*100))))

simple_avg = int(sum(selected_times) / len(selected_times))
print("simple_avg = {:02}:{:02}".format(simple_avg//60,
                                        simple_avg%60))

hh_mm = ["{:02}:{:02}".format(t//60, t%60) for t in selected_times]
print("\ntimes = {}".format(hh_mm))

我的示例的输出:

complex_avg_minutes = 15:45 (relevance = 44%)
simple_avg = 12:25

关于python - 从日期时间获取 SQLite 中的平均时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9408145/

相关文章:

database - 从数据库字段中仅提取大写文本

android - 为什么 blob 值不存储在 android 中的 sqlite 数据库中

sql - 如何在oracle sql中查找某个日期范围内缺失的数据

android - 使用 Phonegap 从 SQLite 数据库为 Android 填充数据

python - GCP Cloud Shell 在哪个目录中运行?

python - 如何在类对象中为 `dtype`参数引发错误

python - 如何在 Flask 上使用 ImmutableMultiDict 获取嵌套字典的值?

python - Facebook 广告预算估算(reach estimate cpm)

sql连接查询问题(mysql)

php - 过滤选择查询以仅返回在连接表中没有对应记录的记录