Django/MySQL中的间隙检测
我有一些时间序列数据存储在MySQL的InnoDB数据库里,我是通过Django的对象关系映射工具来访问这些数据的。
我想问的是:怎样才能最好地识别和找到这些时间序列数据中的空缺部分呢?
补充说明一下:虽然获取所有缺失数据点的列表比较简单,但这并不能完全解决我的问题。我只想知道空缺的开始和结束时间。连续时间段的开始和结束也可以。
再补充说明一下:下面是这个表的MySQL列。时间是标准的Django DateTimeField。相关数据每15分钟采样一次。
mysql> show columns from datalogging_datapoint;
+----------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| new_since_parsing | tinyint(1) | NO | | NULL | |
| non_public | tinyint(1) | NO | | NULL | |
| time | datetime | NO | | NULL | |
| value | double | NO | | NULL | |
| parent_timeseries_id | int(11) | NO | MUL | NULL | |
+----------------------+------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
3 个回答
0
可以看看Python的numpy和scipy这两个包,它们里面可能有一些时间序列分析的功能。接下来就是从数据库中提取数据,这个在Django和Python中是很常见的操作。
你想要的效果是这样的:
def gaps(seq):
...
return gaps_found
也就是说,当输入[1,2,4,5,6,8,12]时,返回的结果是[3,7,9,10,11]?这个可以用集合来实现。
1
你需要提供一些示例数据,以及你希望如何处理这些数据。告诉我们你把数据存储在MySQL或者使用innodb并不是问题的关键(比如,ORM会处理这些事情)。我假设你能够把时间序列数据提取成一个整数列表,而你想要找出这个列表中缺口的开始和结束位置。
def gaps(seq):
seq_set = set(seq) # e.g., set([0, 1, 2, 3, 7, 8, 9, 10, 16, 17, 18])
full_set = set(range(seq[-1]+1)) # set([0,1,2,3,..., 17, 18])
missing_pts = list(seq_set ^ full_set) # [4, 5, 6, 11, 12, 13, 14, 15]
missing_pts.sort() # EDIT: originally didn't have this;
# should have as sets are unordered.
missing_pt_pairs = []
first_pt = missing_pts[0]
prev_pt = missing_pts[0]
for pt in missing_pts:
if pt - prev_pt > 1:
missing_pt_pairs.append((first_pt, prev_pt))
first_pt = pt
prev_pt = pt
missing_pt_pairs.append((first_pt, pt))
return missing_pt_pairs
time_pts = [0,1,2,3,7,8,9,10,16,17,18]
gaps(time_pts) # returns [(4,6), (11,15)],
# indicating that two gaps are present starting from [4,6] and [11,15]
0
谢谢大家的建议!我从你们那里学到了很多。
不过,我觉得我通过在脑海中重新整理问题,找到了一个理想的解决办法。基本的想法是这样的:
Count the values in a that year with Django's .count() .
If not complete:
Count the values for each month in that year
If not complete:
Count the values for each day in that month