Groupby和count / sum与python中的元组列表?

时间:2016-10-28 20:03:59

标签: python python-3.x

我有一个元组列表:

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]

有更好的方法吗?

4 个答案:

答案 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的其他答案解决方案就足够了。