python - 根据时间对列表进行聚类/分组(python)

标签 python python-2.7

我有一个列表列表,我想根据时间集群将其分组为单独的列表。

我可以很容易地根据时间对它进行排序,但我还没有确定一种简单的方法将它们组合在一起。我可以接受日期时间/时间格式或文本,两者都适合我。我需要基于集群处理其他数据。这是我可能会使用的示例数据集。

[['asdf', '2012-01-01 00:00:12', '1234'],
 ['asdf', '2012-01-01 00:00:31', '1235'],
 ['asdf', '2012-01-01 00:00:57', '2345'],
 ['asdf', '2012-01-01 00:01:19', '2346'],
 ['asdf', '2012-01-01 00:01:25', '2345'],
 ['asdf', '2012-01-01 09:04:14', '3465'],
 ['asdf', '2012-01-01 09:04:34', '1613'],
 ['asdf', '2012-01-01 09:04:51', '8636'],
 ['asdf', '2012-01-01 09:05:15', '5847'],
 ['asdf', '2012-01-01 09:05:29', '3672'],
 ['asdf', '2012-01-01 09:05:30', '2367'],
 ['asdf', '2012-01-01 09:05:43', '9544'],
 ['asdf', '2012-01-01 14:48:15', '2572'],
 ['asdf', '2012-01-01 14:48:34', '7483'],
 ['asdf', '2012-01-01 14:48:56', '5782']]

结果应该是这样的。每个组的嵌套列表列表。

[[['asdf', '2012-01-01 00:00:12', '1234'],
  ['asdf', '2012-01-01 00:00:31', '1235'],
  ['asdf', '2012-01-01 00:00:57', '2345'],
  ['asdf', '2012-01-01 00:01:19', '2346'],
  ['asdf', '2012-01-01 00:01:25', '2345']],
 [['asdf', '2012-01-01 09:04:14', '3465'],
  ['asdf', '2012-01-01 09:04:34', '1613'],
  ['asdf', '2012-01-01 09:04:51', '8636'],
  ['asdf', '2012-01-01 09:05:15', '5847'],
  ['asdf', '2012-01-01 09:05:29', '3672'],
  ['asdf', '2012-01-01 09:05:30', '2367'],
  ['asdf', '2012-01-01 09:05:43', '9544']],
 [['asdf', '2012-01-01 14:48:15', '2572'],
  ['asdf', '2012-01-01 14:48:34', '7483'],
  ['asdf', '2012-01-01 14:48:56', '5782']]]

集群没有固定大小,也没有固定时间。它们可以在一天中随机出现,需要根据较大的时间间隔进行聚类。

第一组发生在午夜之后,有 5 个条目,下一个以 09:05 为中心,有 7 个条目。最后一个发生在 14:48 左右,只有 3 个条目。我也可以在每个小时结束时有两个小组,所以我不能只按小时分组。

我已经按列表中的第一个字段对数据进行了排序和分组,我只需要将它们分解成更小的 block 进行处理。我愿意将日期更改为完成分组所需的任何格式,因为这是我对数据进行的分析的关键部分。

我更愿意将解决方案保留在基本的 python 库中,但如果没有解决方案,我可以尝试获取其他包。

我已经看过解决方案here , here , here , here和许多其他人,但没有一个解决这些时代的随机性。

在任何大于 X 时间的间隔处拆分列表将是一个很好的解决方案,因此我可以将 X 更改为 5 或 10 分钟,任何合适的时间。删除任何长度小于 3 的组也是一种奖励,但最后可以轻松完成。

我现在唯一真正的想法是循环遍历列表,将当前时间与新时间进行比较,然后以这种方式拆分列表,但是当有数百万条记录需要排序时,这似乎是解决此问题的一种非常低效的方法和组。

如有任何帮助,我们将不胜感激。如果其中任何一个没有意义,我会尽力澄清。

最佳答案

如果我们在超过某个限制的时间差异时 split ,那么就像

# turn strings into datetimes
date_format = "%Y-%m-%d %H:%M:%S"
for row in data:
    row[1] = datetime.datetime.strptime(row[1], date_format)

split_dt = datetime.timedelta(minutes=5)
dts = (d1[1]-d0[1] for d0, d1 in zip(data, data[1:]))
split_at = [i for i, dt in enumerate(dts, 1) if dt >= split_dt]
groups = [data[i:j] for i, j in zip([0]+split_at, split_at+[None])]

可能会起作用。 (不过要小心 fencepost 错误。我太容易犯错误了!)

关于python - 根据时间对列表进行聚类/分组(python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20112143/

相关文章:

python - Odoo:如何在服务器代码中放置调试行以在/var/log/odoo 中查看

python - python 3.4.3 中 urllib.httperror 的语法错误

python - 在 python 中,你可以在命名参数之后传递可变参数吗?

python - python 2.7 中的 super

python - python中的命中或未命中形态在图像中查找结构未提供所需的结果

python-2.7 - 是否可以忽略硬编码的 pdb 断点?

python : Remove duplicate elements in lists and sublists; and remove full sublist if duplicate

python - 如何更新集合?

python - Xerces + Python?

Python 3 List : How do I sort [ ('NJ' , 81), ('CA' , 81), ('DC' , 52)] 基于数字然后字母?