2013-03-06 19 views
12

Kısa bir süre önce R'den python'a geçiş yaptım ve R's data.table kullanmanın tersine veri çerçevelerine yeniden alışmakta sorun yaşıyorum. Yapmakta olduğum problem, bir dizi dizgeyi almak, bir değer olup olmadığını kontrol etmek, sonra o dizgenin sayımını kullanıcı tarafından parçalanmaktır.pandalar kümelenmesi için koşullu toplamlar

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 

Ve dönüş: Bu yüzden bu verileri almak istiyorum

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 

Ben R koduyla yaptım Önce Ancak

>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)]; 

tüm (data.table kullanarak) Python ile yaptığım son denemeler beni başarısızlığa uğrattı:

Teşekkür peşin! Basit bir soru gibi görünüyor, ancak hiçbir yerde bulamadım.

cevap

14

unutbu cevabını tamamlamak için verir, burada GroupBy nesne üzerinde apply kullanarak bir yaklaşımdır.

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

Daha iyi bir yol olabilir; Ben pandalar oldukça yeniyim ama bu işleri:

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