2017-01-12 12 views
1

Ich habe einen Pandas DataFrame.Summe einer Spalte in Pandas DataFrame

LeafId pidx pidy count 
    1  x  y  10 
    1  x  y  20 
    1  x  z  30 
    3  b  q  10 
    1  x  y  20 

Wir können sehen, dass es mehrere Reihen von pidx = x and pidy = y

Ich möchte die Zählspalte zusammenzufassen und Datenrahmen df2 erhalten wie:

LeafId pidx pidy count 
    1  x  y  50 
    1  x  z  30 
    3  b  q  10 

Ich kenne einen Weg, es zu tun:

df2 = df.groupby(['pidx','pidy']).agg({'LeafID':'first',count':'sum'}).reset_index() 

Aber ich möchte die effizienteste Art, es für einen riesigen DataFrame zu tun (Mühle Ionen von Aufzeichnungen), die die geringste Zeit benötigen.

Gibt es einen besseren Weg, dies zu tun?

Auch statt LeafID innerhalb .agg() setzen, kann ich Folgendes tun?

df2 = df.groupby(['LeafID','pidx','pidy']).agg({count':'sum'}).reset_index() 
+0

Sortiere nach pidx und pidy, finde Indizes, wo sich entweder die Änderungen ändern, und wende dann die Summe auf die Bereiche an. – rafaelvalle

Antwort

2

Wenn Bedarf groupby von LeafId, pidx und pidy Spalten:

df1 = df.groupby(['LeafId','pidx','pidy'], as_index=False)['count'].sum() 
print (df1) 
    LeafId pidx pidy count 
0  1 x y  50 
1  1 x z  30 
2  3 b q  10 

ich versuchen, einige Timings:

np.random.seed(123) 
N = 1000000 

L1 = list('abcdefghijklmnopqrstu') 
L2 = list('efghijklmnopqrstuvwxyz') 
df = pd.DataFrame({'LeafId':np.random.randint(1000, size=N), 
        'pidx': np.random.choice(L1, N), 
        'pidy': np.random.choice(L2, N), 
        'count':np.random.randint(1000, size=N)}) 
#print (df) 

print (df.groupby(['LeafId','pidx','pidy'], as_index=False)['count'].sum()) 
print (df.groupby(['LeafId','pidx','pidy']).agg({'count':'sum'}).reset_index()) 

In [261]: %timeit (df.groupby(['LeafId','pidx','pidy'], as_index=False)['count'].sum()) 
1 loop, best of 3: 544 ms per loop 

In [262]: %timeit (df.groupby(['LeafId','pidx','pidy']).agg({'count':'sum'}).reset_index()) 
1 loop, best of 3: 466 ms per loop 

Kleinere Gruppen 1000-10000:

np.random.seed(123) 
N = 1000000 

L1 = list('abcdefghijklmnopqrstu') 
L2 = list('efghijklmnopqrstuvwxyz') 
df = pd.DataFrame({'LeafId':np.random.randint(10000, size=N), 
        'pidx': np.random.choice(L1, N), 
        'pidy': np.random.choice(L2, N), 
        'count':np.random.randint(10000, size=N)}) 
print (df) 

print (df.groupby(['LeafId','pidx','pidy'], as_index=False)['count'].sum()) 
print (df.groupby(['LeafId','pidx','pidy']).agg({'count':'sum'}).reset_index()) 

In [264]: %timeit (df.groupby(['LeafId','pidx','pidy'], as_index=False)['count'].sum()) 
1 loop, best of 3: 933 ms per loop 

In [265]: %timeit (df.groupby(['LeafId','pidx','pidy']).agg({'count':'sum'}).reset_index()) 
1 loop, best of 3: 775 ms per loop 
+0

2 Fragen, würde meine Methode der .agg arbeiten und wenn ja, wird Ihre Antwort schneller sein als .agg? – Shubham

+0

@SRingne Probieren Sie es aus. Seit du gesagt hast, dein DF ist riesig. Lassen Sie uns die Zeiten wissen. – MYGz

+1

@jezrael '.sum()' und explizite 'column.sum()' wird hier einen Unterschied machen, da es nur 1 Spalte gibt? – MYGz

Verwandte Themen