Python - группировать и суммировать список кортежей
Учитывая следующий список:
[
('A', '', Decimal('4.0000000000'), 1330, datetime.datetime(2012, 6, 8, 0, 0)),
('B', '', Decimal('31.0000000000'), 1330, datetime.datetime(2012, 6, 4, 0, 0)),
('AA', 'C', Decimal('31.0000000000'), 1330, datetime.datetime(2012, 5, 31, 0, 0)),
('B', '', Decimal('7.0000000000'), 1330, datetime.datetime(2012, 5, 24, 0, 0)),
('A', '', Decimal('21.0000000000'), 1330, datetime.datetime(2012, 5, 14, 0, 0))
]
Я хотел бы сгруппировать их по первому, второму, четвертому и пятому столбцам в кортеже и сумме третьего.
В этом примере я буду называть столбцы как col1, col2, col3, col4, col5.
В SQL я бы сделал что-то вроде этого:
select col1, col2, sum(col3), col4, col5 from my table
group by col1, col2, col4, col5
Есть ли "классный" способ сделать это или все это ручной цикл?
Ответы
Ответ 1
>>> [(x[0:2] + (sum(z[2] for z in y),) + x[2:5]) for (x, y) in
itertools.groupby(sorted(L, key=operator.itemgetter(0, 1, 3, 4)),
key=operator.itemgetter(0, 1, 3, 4))]
[
('A', '', Decimal('21.0000000000'), 1330, datetime.datetime(2012, 5, 14, 0, 0)),
('A', '', Decimal('4.0000000000'), 1330, datetime.datetime(2012, 6, 8, 0, 0)),
('AA', 'C', Decimal('31.0000000000'), 1330, datetime.datetime(2012, 5, 31, 0, 0)),
('B', '', Decimal('7.0000000000'), 1330, datetime.datetime(2012, 5, 24, 0, 0)),
('B', '', Decimal('31.0000000000'), 1330, datetime.datetime(2012, 6, 4, 0, 0))
]
(ПРИМЕЧАНИЕ: выход переформатирован)
Ответ 2
Вы хотите itertools.groupby
.
Обратите внимание, что groupby
ожидает, что ввод будет отсортирован, поэтому вам может потребоваться сделать это перед рукой:
keyfunc = lambda t: (t[0], t[1], t[3], t[4])
data.sort(key=keyfunc)
for key, rows in itertools.groupby(data, keyfunc):
print key, sum(r[2] for r in rows)
Ответ 3
Если вы обнаружите, что делаете это с большими наборами данных, вы можете посмотреть в библиотеке pandas, в которой много хорошие возможности для такого рода вещей.