在Python中将每日数据汇总并求和为月数据
我在Python中有一个二维列表,这个列表里包含了一天的时间戳(以秒为单位)和相应的值。我需要把这个列表整理成一个包含月份和每天值总和的json数组。
这个Python列表看起来是这样的:
array = [[1230768000000, 23], [1244073599000, 5], [1269206974000, 8], [1291908086000, 23]...]
我想把它转换成一个这样的json数组:
[{key:'2009-01',value:28},{key:'2009-02',value:324} ... ]
我试过以下代码,但输出的结果并不是我想要的。
month_aggregate = defaultdict(list)
for [d,v] in array:
truncated = int(str(d)[:-3])
year_month = datetime.utcfromtimestamp(truncated).date().isoformat()[:-3]
month_aggregate[year_month].append(v)
>> {'2011-08': [559, 601, 545, 578], '2011-09': [572, 491, 595], ... }
非常感谢任何建议!
4 个回答
0
这正是 groupby
在 itertools 中的用途。这个功能可以把数据分组,它会根据你给定的函数来判断每个项目属于哪个组,并为每个组返回一个迭代器,这个迭代器可以遍历该组中的所有项目。
from itertools import groupby
from time import gmtime, strftime
# gmtime uses the UTC timezone, use the function localtime if preferred
def get_year_month_from_datum((millis, _value)):
return strftime("%Y-%m", gmtime(millis / 1000))
aggregate = {key: sum(value for _time, value in values)
for key, values in groupby(array, get_year_month_from_datum)}
json_aggr = [{"key": key, "value": sum(value for _time, value in values)}
for key, values in groupby(array, get_year_month_from_datum)]
groupby
函数假设输入的数组已经按照分组的标准进行了排序。如果没有排序,可以用 sorted(array)
来替代 array
进行分组,这样也能正常工作。
0
下面的回答使用了Collections里的Counter类,这个类可能是解决这个问题的最佳和最快的数据类型。
from operator import add
from collections import Counter
l = [[1230768000000, 23], [1244073599000, 5], [1269206974000, 8], [1291908086000, 23]]
getDate = lambda x: time.strftime('%Y-%m', time.localtime(x/1000))
counter = reduce(add,[Counter({getDate(key):val}) for key,val in l])
到这里,你已经有了一个很不错的Collections数据类型,里面包含了你所有的信息。如果你想把它再转换回json格式,只需要用列表推导式就可以了……
json = [{'key':k,'value':v} for k,v in counter.iteritems()]
0
试试使用collections里的Counter。我前几天发现这个工具,真的很有用。
from collections import Counter
month_aggregate = Counter()
for [d,v] in array:
truncated = int(str(d)[:-3])
year_month = datetime.utcfromtimestamp(truncated).date().isoformat()[:-3]
month_aggregate[year_month] += v
[{"key":k, "value":v} for k,v in month_aggregate.items()]
结果是:
[{'key': '2009-06', 'value': 5},
{'key': '2010-03', 'value': 8},
{'key': '2010-12', 'value': 23},
{'key': '2009-01', 'value': 23}]
1
试试这个:
array = [[1230768000000, 23], [1244073599000, 5], [1269206974000, 8], [1291908086000, 23]]
month_aggregate = dict()
for [d,v] in array:
truncated = int(str(d)[:-3])
year_month = datetime.utcfromtimestamp(truncated).date().isoformat()[:-3]
# If the entry was not present previously create one with the current value v
if not month_aggregate.has_key(year_month):
month_aggregate[year_month] = v
else:
# Otherwise add the value to the previous entry
month_aggregate[year_month] += v
# Create a JSON Array from the month_aggregate dictionary
month_aggregate_json_list = [ {'value':v, 'key':k} for k, v in month_aggregate.iteritems() ]
print month_aggregate_json_list
会得到这个结果
[{'key': '2009-01', 'value': 23}, {'key': '2009-06', 'value': 5}, {'key': '2010-03', 'value': 8}, {'key': '2010-12', 'value': 23}]