2016-10-28 13 views
2

私はタプルのリストを持っている:PythonのGroupbyとタプルのリストの数/合計?

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])GROUPBYしたい各チームに番号または人を数える(インデックス[1])と数字を合計します各チーム(インデックス[2])に関連していますが、私はこれを理解できません。

def create_hrs_totals(): 
    result = defaultdict(list) 
    for k, *v in data(): 
     result[k] += v 
    return dict(result) 

が、その後、私は私が使用して必要なものを達成するためにその出力での作業に苦しんでいます。これまでのところ、私は辞書を返すdefaultdict(リスト)を使用して試してみましたが、例えば私はチームがグループにこれを試してみましたリストの候補者など何か...私が探している結果は新しいリストです:

[Team1, 4, 145, 
Team2, 2, 80, 
Team3, 2, 70] 

もっと良い方法がありますか?

答えて

4

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

これは私が必要とするものと最もよくマッチします。私はタイプエラーを防ぐためにd [team] [1] + = int(number)を実行する必要がありましたが、そうでなければすべていいです、ありがとう:-) – MattE

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}} 
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} 

これらのジェネレーター/補題はおそらく少し混乱させるかもしれませんが、から選択する答え!

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ベースのソリューションが十分にあります。

関連する問題