如何在Python中重塑和聚合元组列表?
我刚接触Python,所以如果我的问题看起来很简单,请多多包涵。
我从一个psycopg2的查询中得到了一个结果,这个结果是一个包含元组的列表,样子是这样的:
[(1, 0), (1, 0), (1, 1), (2, 1), (2, 2), (2, 2), (2, 2)]
每个元组代表一个事件发生的地点ID和事件发生的小时。
我想把这个列表重新整理和汇总,显示每个地点每个小时的事件小计,最终的样子应该是这样的:
[(1, 0, 2), (1, 1, 1), (1, 2, 0), (2, 0, 0), (2, 1, 1), (2, 3, 3)]
每个元组现在会告诉我,比如说:在地点1,0点有2个事件;在地点1,1点有1个事件;依此类推……
如果某个小时没有事件发生,我也希望能看到,比如说在地点2的0点有0个事件: (2, 0, 0)
我该如何在Python中实现这个呢?
编辑:谢谢大家的帮助!
2 个回答
2
像这样…:
import collections
raw_data = [(1, 0), (1, 0), (1, 1), (2, 1), (2, 2), (2, 2), (2, 2)]
aux = collections.defaultdict(int)
for x, y in raw_data:
aux[x, y] += 1
locations = sorted(set(x for x, y in raw_data))
hours = sorted(set(y for x, y in raw_data))
result = [(x, y, aux[x, y]) for x in locations for y in hours]
如果你想让地点和时间显示的内容与原始数据一致,你可能想对地点和时间分别使用 range(some, thing)
。这样做是因为你可能有独立的信息,知道地点和时间应该覆盖的范围,而这些范围和 raw_data
中实际的时间和地点是分开的。
1
如果你是从数据库里获取这些数据,那为什么不让查询直接处理这些呢?可以用类似这样的语句:SELECT hour, location, COUNT(*) FROM events GROUP BY hour, location ORDER BY hour, location
。
在Python中,可能可以写成这样:
timed_events = {}
# Count them up
for event in events_from_database:
timed_events[event] = timed_events.setdefault(event, 0) + 1
# Form a new list with the original data plus the count
aggregate_list = [(evt[0], evt[1], count) for evt,count in events.items()]