我为可视化准备了一个数据。数据结构是这样的:
data = [{u'count': 1, u'_id': {u'year': 2010, u'month': 4}}, {u'count': 1, u'_id': {u'year': 2010, u'month': 5}}, {u'count': 2, u'_id': {u'year': 2010, u'month': 7}}, {u'count': 1, u'_id': {u'year': 2010, u'month': 9}}, {u'count': 1, u'_id': {u'year': 2010, u'month': 10}}, {u'count': 4, u'_id': {u'year': 2010, u'month': 12}}]
我用这种方式将它们转换为带有时间戳和计数变量的列表:
chart = []
for month in data:
d = datetime.datetime.strptime(str(month['_id']['year'])+"-"+str(month['_id']['month']),'%Y-%m')
dat = time.mktime(d.timetuple())
chart.append([dat*1000,month['count']])
结果在某种程度上是这样的(该示例与输入数据的示例不符)
chart: [[1220216400000.0, 1], [1222808400000.0, 8], [1225490400000.0, 1], [1228082400000.0, 6], [1230760800000.0, 4], [1233439200000.0, 1], [1235858400000.0, 1], [1238533200000.0, 1], [1241125200000.0, 2], [1243803600000.0, 1], [1246395600000.0, 1], [1249074000000.0, 1]]
我正在尝试做的是更改代码以包括第一个和最后一个日期之间缺少的月份,count=0。例如,在数据中,从 2010 年第 5 个月开始,下一个字段是第 10 个月第 7 个月。缺少第 6 个月,我想将其包含在 count=0 中。
知道吗?
这是一个使用dateutil
库每月迭代日期范围的解决方案。
这个想法是初始化一个OrderedDict
,datetime
作为键,count
作为值。然后,对于有序字典中的每个项目,每月迭代当前和以前添加的项目之间的日期范围,并添加0
计数:
from collections import OrderedDict
import datetime
from pprint import pprint
import time
from dateutil.rrule import rrule, MONTHLY
data = [{u'count': 1, u'_id': {u'year': 2010, u'month': 4}}, {u'count': 1, u'_id': {u'year': 2010, u'month': 5}},
{u'count': 2, u'_id': {u'year': 2010, u'month': 7}}, {u'count': 1, u'_id': {u'year': 2010, u'month': 9}},
{u'count': 1, u'_id': {u'year': 2010, u'month': 10}}, {u'count': 4, u'_id': {u'year': 2010, u'month': 12}}]
new_data = OrderedDict()
for item in data:
year, month = item['_id']['year'], item['_id']['month']
d = datetime.datetime.strptime(str(year) + "-" + str(month), '%Y-%m')
new_data[d] = item['count']
chart = {}
last_added = None
for d, count in new_data.iteritems():
date_start = last_added if last_added else d
for dt in rrule(MONTHLY, dtstart=date_start, until=d):
key = time.mktime(dt.timetuple()) * 1000
if key not in chart:
chart[key] = count if dt == d else 0
last_added = d
pprint(sorted(chart.items()))
指纹:
[(1270094400000.0, 1),
(1272686400000.0, 1),
(1275364800000.0, 0),
(1277956800000.0, 2),
(1280635200000.0, 0),
(1283313600000.0, 1),
(1285905600000.0, 1),
(1288584000000.0, 0),
(1291179600000.0, 4)]
希望它对你有用。
这里有一种方法可以做到这一点。
这个想法是有一个字典dat
-> count
.如果您不知道数据中的年份,则需要在每次迭代时初始化每月数据:
import datetime
from pprint import pprint
import time
data = [{u'count': 1, u'_id': {u'year': 2010, u'month': 4}}, {u'count': 1, u'_id': {u'year': 2010, u'month': 5}},
{u'count': 2, u'_id': {u'year': 2010, u'month': 7}}, {u'count': 1, u'_id': {u'year': 2010, u'month': 9}},
{u'count': 1, u'_id': {u'year': 2010, u'month': 10}}, {u'count': 4, u'_id': {u'year': 2010, u'month': 12}}]
chart = {}
for month in data:
year = month['_id']['year']
for m in xrange(1, 12):
d = datetime.datetime.strptime(str(year) + "-" + str(m), '%Y-%m')
dat = time.mktime(d.timetuple()) * 1000
if dat not in chart:
chart[dat] = 0
d = datetime.datetime.strptime(str(year) + "-" + str(month['_id']['month']), '%Y-%m')
dat = time.mktime(d.timetuple()) * 1000
chart[dat] = month['count']
pprint(sorted(chart.items()))
如果您知道数据中的年份 - 在循环data
之前初始化月份计数。
指纹:
[(1262322000000.0, 0),
(1265000400000.0, 0),
(1267419600000.0, 0),
(1270094400000.0, 1),
(1272686400000.0, 1),
(1275364800000.0, 0),
(1277956800000.0, 2),
(1280635200000.0, 0),
(1283313600000.0, 1),
(1285905600000.0, 1),
(1288584000000.0, 0),
(1291179600000.0, 4)]
请参阅-缺少的月份与0
计数。
希望有帮助。
我看到您的列表已排序,因此您只需要记住上一个日期(最初设置为 1)并用缺少的元素填充列表(如果有的话)(即如果month['_id']['month']
和上一个日期之间的差异大于 1)。