我有一个元组列表:
data = [('Team1', 'Mark Owen', 40),
('Team1', 'John Doe', 25),
('Team2', 'Raj Patel', 40),
('Team3', 'Matt Le Blanc', 30),
('Team1', 'Rene Russo', 40),
('Team1', 'Ronald Regan', 40),
('Team3', 'Dean Saunders', 15),
('Team2', 'Michael Antonio', 30)]
我想分组(每个元组的索引[0]),计算每个团队中的数量或人数(索引[1])并将每个团队相关的数字相加(索引[2])但我不能非常清楚这一点。到目前为止,我已经尝试使用defaultdict(list)返回一个dict,例如我已尝试按团队分组:
def create_hrs_totals():
result = defaultdict(list)
for k, *v in data():
result[k] += v
return dict(result)
然后我正在努力使用输出来实现我需要的列表组件或其他...我正在寻找的结果是一个新列表:
[Team1, 4, 145,
Team2, 2, 80,
Team3, 2, 70]
有更好的方法吗?
答案 0 :(得分:5)
groupby
是来自itertools
的函数,但它并不是您想要的。相反,我们可以从defaultdict
collections
from collections import defaultdict
def data_by_team(data):
d = defaultdict(lambda: [0,0])
for team, name, number in data:
d[team][0] += 1
d[team][1] += number
return d
这将返回一个defaultdict
,用于将团队名称映射到包含玩家数量及其数量总和的列表。
答案 1 :(得分:2)
您可以这样做:
from collections import defaultdict
out = defaultdict(dict)
for team, name, num in data:
out[team].setdefault('count', 0)
out[team].setdefault('sum', 0)
out[team]['count'] += 1
out[team]['sum'] += num
print dict(out)
结果:
{'Team1': {'count': 4, 'sum': 145},
'Team2': {'count': 2, 'sum': 70},
'Team3': {'count': 2, 'sum': 45}}
答案 2 :(得分:1)
这可能是一个很好的干净方式,但做得少一点......
count = {row[0]:sum((1 for _row in data if _row[0] == row[0])) for row in data}
num = {row[0]:sum((_row[2] for _row in data if _row[0] == row[0])) for row in data}
这些生成器/理解可能写得有点混乱,但你已经有了很多答案可供选择!
答案 3 :(得分:1)
如果您需要经常对此进行不同的变体,可以使用pivot table,例如pandas.pivot_table()
:
>>> import numpy as np
>>> import pandas ad pd
>>> df = pd.DataFrame(data, columns=['team', 'person', 'number'])
>>> df
team person number
0 Team1 Mark Owen 40
1 Team1 John Doe 25
2 Team2 Raj Patel 40
3 Team3 Matt Le Blanc 30
4 Team1 Rene Russo 40
5 Team1 Ronald Regan 40
6 Team3 Dean Saunders 15
7 Team2 Michael Antonio 30
>>> pd.pivot_table(df, index=['team'],
... aggfunc={'person': lambda s: np.unique(s).size, 'number': np.sum})
number person
team
Team1 145 4
Team2 70 2
Team3 45 2
否则,基于defaultdict
的其他答案解决方案就足够了。