2013-07-16 8 views
16

I mają następujące pytona pandas ramki danych:pyton pandy GroupBy() wynik

df = pd.DataFrame({ 
    'A': [1,1,1,1,2,2,2,3,3,4,4,4], 
    'B': [5,5,6,7,5,6,6,7,7,6,7,7], 
    'C': [1,1,1,1,1,1,1,1,1,1,1,1] 
    }); 

df 
    A B C 
0 1 5 1 
1 1 5 1 
2 1 6 1 
3 1 7 1 
4 2 5 1 
5 2 6 1 
6 2 6 1 
7 3 7 1 
8 3 7 1 
9 4 6 1 
10 4 7 1 
11 4 7 1 

chciałbym mieć inną kolumnę do przechowywania sumy wartości stosunku C do stałej wartości (oba) A i B. Oznacza to, że coś takiego:

A B C D 
0 1 5 1 2 
1 1 5 1 2 
2 1 6 1 1 
3 1 7 1 1 
4 2 5 1 1 
5 2 6 1 2 
6 2 6 1 2 
7 3 7 1 2 
8 3 7 1 2 
9 4 6 1 1 
10 4 7 1 2 
11 4 7 1 2 

próbowałem z pand groupby i to niby działa:

res = {} 
for a, group_by_A in df.groupby('A'): 
    group_by_B = group_by_A.groupby('B', as_index = False) 
    res[a] = group_by_B['C'].sum() 

ale nie wiem jak "dostać" wyniki z res do df w uporządkowany sposób. Byłby bardzo zadowolony z wszelkich porad na ten temat. Dziękuję Ci.

Odpowiedz

13

Oto jeden sposób (choć wydaje się, że powinien działać za jednym razem, a nie mogę go otrzymać).

In [11]: g = df.groupby(['A', 'B']) 

In [12]: df1 = df.set_index(['A', 'B']) 

size funkcja GroupBy jest jeden chcesz, musimy dopasować go do „A” i „B” jako index:

In [13]: df1['D'] = g.size() # unfortunately this doesn't play nice with as_index=False 
# Same would work with g['C'].sum() 

In [14]: df1.reset_index() 
Out[14]: 
    A B C D 
0 1 5 1 2 
1 1 5 1 2 
2 1 6 1 1 
3 1 7 1 1 
4 2 5 1 1 
5 2 6 1 2 
6 2 6 1 2 
7 3 7 1 2 
8 3 7 1 2 
9 4 6 1 1 
10 4 7 1 2 
11 4 7 1 2 
+0

Dziękuję @Andy Hayden! Rozwiązanie z 'sumą' jest bardziej ogólne, jak sądzę. W rzeczywistości nie mam '1' w' C' (kiedy 'size' działa idealnie, jak wskazałeś w swoim rozwiązaniu), ale raczej niektóre zmienne, więc żeby to działało poprawnie, muszę iść z' '' '' ' suma ". Ale w każdym razie, genialne, jeszcze raz dziękuję. –

+4

Myślę, że jednym linerem, o którym marzyłeś, jest '' df ['D'] = df.groupby (['A', 'B']). Transform (np.size) ''. W dobrych i złych czasach istnieje "transformacja". :-D –

6

Można również zrobić jedną wkładkę stosując scalić w następujący sposób:

df = df.merge(pd.DataFrame({'D':df.groupby(['A', 'B'])['C'].size()}), left_on=['A', 'B'], right_index=True) 
+0

łatwy do odczytania i zrozumienia – jiamo

5

można również zrobić jedną wkładkę przy użyciu transformaty stosowane do GroupBy:

df['D'] = df.groupby(['A','B'])['C'].transform('sum') 
Powiązane problemy