在Python中将每日数据汇总并求和为月数据

1 投票
4 回答
3458 浏览
提问于 2025-04-18 14:40

我在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}]

撰写回答