2013-07-16 5 views
16

У меня есть следующий питона панд фрейм данных:Python панд GroupBy() результат

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 

Я хотел бы иметь еще один столбец, хранящий значение суммы над значениями C для фиксированного (оба) А и В. то есть, что-то вроде:

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 

Я попытался с пандами groupby и вид работ:

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

, но я не знаю, как «получить» результаты от res до df в упорядоченном порядке. Был бы очень доволен любым советом по этому поводу. Спасибо.

ответ

13

Вот один из способов (хотя он чувствует, что это должно работать в одно время с применением, я не могу его получить).

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

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

size функция GroupBy является тот, который вы хотите, мы должны соответствовать его на «A» и «B», как индекс:

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

Спасибо @ Энди Хайден! Думаю, решение с 'sum' является более общим. На самом деле, у меня нет '' '' '' '' '' '' '' '' '' '' '' '' 'отлично работает, как вы указали в своем решении), а скорее некоторые поплавки, поэтому, чтобы это правильно работало, мне нужно пойти с' sum'. Но в любом случае, блестящий, еще раз спасибо. –

+4

Я думаю, что с одним лайнером, о котором вы мечтали, является '' df ['D'] = df.groupby (['A', 'B']). Transform (np.size) ''. В хорошие и плохие времена '' transform'' есть. : -D –

6

Вы можете также сделать один вкладыш с использованием слияния следующим образом:

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

легко читать и понимать – jiamo

5

Вы также могли бы сделать один лайнер, используя преобразование применяется к GroupBy:

df['D'] = df.groupby(['A','B'])['C'].transform('sum') 
Смежные вопросы