2013-03-06 36 views
12

私は最近、Rからpythonへの切り替えを行い、Rのdata.tableを使用するのとは対照的に、データフレームに再び慣れていく上でいくつかの問題を抱えています。私が抱えていた問題は、文字列のリストを取得し、値をチェックしてから、その文字列の数を合計し、ユーザー別に合計したいということです。パンダ集計の条件付き合計

A_id  B C 
1: a1 "up" 100 
2: a2 "down" 102 
3: a3 "up" 100 
3: a3 "up" 250 
4: a4 "left" 100 
5: a5 "right" 102 

とリターン:だから私は、このデータを利用したいと思い

A_id_grouped sum_up sum_down ... over_200_up 
1:   a1  1   0 ...   0 
2:   a2  0   1     0 
3:   a3  2   0 ...   1 
4:   a4  0   0     0 
5:   a5  0   0 ...   0 

私はRのコードでそれをやった前しかし

>DT[ ,list(A_id_grouped, sum_up = sum(B == "up"), 
+ sum_down = sum(B == "down"), 
+ ..., 
+ over_200_up = sum(up == "up" & < 200), by=list(A)]; 

のすべて(data.table使用します)私の最近のPythonの試みは失敗しました:

DT.agg({"D": [np.sum(DT[DT["B"]=="up"]),np.sum(DT[DT["B"]=="up"])], ... 
    "C": np.sum(DT[(DT["B"]=="up") & (DT["C"]>200)]) 
    }) 

ありがとうございます!それは簡単な質問のように思えますが、私はそれをどこでも見つけることができませんでした。

答えて

14

unutbuの答えを補完するために、ここではGROUPBYオブジェクトにapplyを使用してのアプローチです。

>>> df.groupby('A_id').apply(lambda x: pd.Series(dict(
    sum_up=(x.B == 'up').sum(), 
    sum_down=(x.B == 'down').sum(), 
    over_200_up=((x.B == 'up') & (x.C > 200)).sum() 
))) 
     over_200_up sum_down sum_up 
A_id        
a1    0   0  1 
a2    0   1  0 
a3    1   0  2 
a4    0   0  0 
a5    0   0  0 
6

もっと良い方法があるかもしれません。私はパンダにかなり新しいんだけど、この作品:

import pandas as pd 
import numpy as np 

df = pd.DataFrame({'A_id':'a1 a2 a3 a3 a4 a5'.split(), 
        'B': 'up down up up left right'.split(), 
        'C': [100, 102, 100, 250, 100, 102]}) 

df['D'] = (df['B']=='up') & (df['C'] > 200) 
grouped = df.groupby(['A_id']) 

def sum_up(grp): 
    return np.sum(grp=='up') 
def sum_down(grp): 
    return np.sum(grp=='down') 
def over_200_up(grp): 
    return np.sum(grp) 

result = grouped.agg({'B': [sum_up, sum_down], 
         'D': [over_200_up]}) 
result.columns = [col[1] for col in result.columns] 
print(result) 

利回り

 sum_up sum_down over_200_up 
A_id        
a1   1   0   0 
a2   0   1   0 
a3   2   0   1 
a4   0   0   0 
a5   0   0   0