python - 寻找一种方法来组织从几天到 session 的 GPS 数据(连续数据延伸到第二天的情况)

标签 python algorithm sorting

我有数千个按日期和时间存储的记录 GPS 点,分解成它们的源视频,每个视频都是每分钟创建的。

session 是指 GPS 记录器从开始到结束的时间,在少数情况下是从晚上 9 点到第二天凌晨 4 点。它们在时间上至少相隔 6 小时,但通常更像是 12 小时。

不幸的是,当我收集原始数据时,无法知道我是否将一个 session 分解到下一个 session ,并且至少有十几次从一个日期开始并延伸到下一个日期的记录 block 被分开了。现在我想弄清楚如何将它们重新组织起来。

所有数据都存储在 sqlite 数据库中,其模式如下:

session
    date
    videos # relationship(Video)

Video:
    datetime # includes the minute of the day it was recorded
    coordinates # relationship(Coordinates)

Coordinate:
    latitude = string # (not float to avoid loss of precision)
    longitude = string 
    datetime = # includes the date, minute, and second

我试过这样的蛮力方法

def find_gaps():
   """
       Assume the bulk of a session's videos are in the correct
       location but the head or tail may not be

       12567
       12,567
       89012567
       89012, 567

   """

   for session in db.Session.query.order_by(db.Session.date.asc()):
       videos = list(session.videos)
       blocks = list()
       block = [videos.pop(0)]
       for video in videos:
           delta = video.datetime - block[-1].datetime
           minutes = delta.seconds / 60
           print(delta.days, minutes)
           if minutes > 15:
               print(video.name, minutes)
               blocks.append(block)
               block = [video]
           else:
               block.append(video)

       if block:
           blocks.append(block)

   if len(blocks) > 1:
       print(len(blocks))

但从未实现排序逻辑,因为我意识到这仍然会使重叠两个日期的 session 保持分开。

我的另一个想法是以重叠的三天(前一天、当天、第二天)为一组遍历所有视频记录(日期时间 - 小时和分钟),但我想不出一种方法来找到实际 session 。

不相关

我记录了我在 Lyft 的驾驶时间以及从丹佛到安克雷奇、阿拉斯加再返回的公路旅行(我喜欢开车)。公路旅行数据对我来说更重要,但也是最复杂的,尤其是去年的数据集。我从一 block 流浪的岩石上打碎了我的天窗,然后撕碎了一个轮胎,所以我最终在 70 公里/小时(~45 英里/小时)的速度下以 70 公里/小时(~45 英里/小时)的速度跑了 12 小时,并在 6 小时的休息时间里停下来,一瘸一拐地走了 3200 英里。

最佳答案

如果您有最新版本的 SQLite,它将支持 window functions .如果您没有最新版本,则可以相当轻松地进行升级。我强烈建议使用它。

窗口函数在 SQL 中提供了一种方法,可以有效地执行按顺序排列数据集、然后比较邻居、运行选项卡等操作。语法有点繁琐,解决起来自然会出现嵌套查询。需要一点时间来适应。

首先,让我们编写一个查询,为我们提供 Video 以及上一个视频的日期时间(警告,所有查询都未经测试,可能会被破坏)

SELECT datetime
  , coordinates
  , lag(datetime) OVER (ORDER BY strftime('%s',datetime)) as last_datetime
FROM Video

(请注意,默认帧在当前行之前是无界的,这意味着我们可以访问以前的视频,但不能访问 future 的视频。我将再次使用该事实,但不会记录下来。)

现在让我们进行一个相同的查询,只是我们知道哪些条目开始了一个 session ,我将其定义为前一小时没有任何条目。

SELECT datetime
  , coordinates
  , CASE
       WHEN strftime('%s',datetime) - strftime('%s',last_datetime) < 3600
       THEN 0
       ELSE 1
    END as is_session_start
FROM (
    SELECT datetime
      , coordinates
      , lag(datetime) OVER (ORDER BY strftime('%s',datetime)) as last_datetime
    FROM Video
  ) AS video_and_prev_datetime

现在我们将使用 session 开始的日期时间标记每个视频。

SELECT datetime
  , coordinates
  , MAX (
      CASE
        WHEN is_session_start = 1
        THEN strftime('%s',datetime)
        ELSE 0
      END
    ) OVER (
      ORDER BY strftime('%s',datetime)
    ) AS session_start
FROM (
    SELECT datetime
      , coordinates
      , CASE
           WHEN strftime('%s',datetime) - strftime('%s',last_datetime) < 3600
           THEN 0
           ELSE 1
        END as is_session_start
    FROM (
        SELECT datetime
          , coordinates
          , lag(datetime) OVER (ORDER BY strftime('%s',datetime)) as last_datetime
        FROM Video
      ) AS video_and_prev_datetime
  ) as video_and_session_start

现在您的视频已按 session 开始时间分类。


如果您更喜欢在代码中执行此操作,我建议只需按 strftime('%s',datetime)Video 进行排序,然后执行相同类型的“比较”最后,跟踪 session 启动并将它们添加到代码中。但随着时间的推移,越来越多的数据库使用窗口函数,您不妨了解如何使用它们,就像我刚才演示的那样。

关于python - 寻找一种方法来组织从几天到 session 的 GPS 数据(连续数据延伸到第二天的情况),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56961163/

相关文章:

python - 从 csv 文件 Python 中的位置列表中查找最近的位置

python - 重新加载 django 模型以处理单元测试中的 @override_settings

python - 具有未知字符串格式的扩展元组解包

python - 在进程中每隔一段时间执行一次任务

algorithm - 将平行线与正交二维网格相交

java - 实现 SparseMatrix 的有效方法

python - 这种排序方法使用什么算法?

python - 创建特定大小的 Numpy 数组,然后以步进速率填充值

javascript - 是否需要全功能的语音搜索算法?

android - 排序的联系人列表有重复项,为什么?