2014-01-23 2 views
5

Давайте предположим, что у нас есть таблица:Как считать все положительные и отрицательные значения в группе pandas?

df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 
        'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 
        'C' : np.random.randn(8), 'D' : np.random.randn(8)}) 

Выход:

 A  B   C   D 
0 foo  one -1.304026 0.237045 
1 bar  one  0.030488 -0.672931 
2 foo  two  0.530976 -0.669559 
3 bar  three -0.004624 -1.604039 
4 foo  two -0.247809 -1.571291 
5 bar  two -0.570580 1.454514 
6 foo  one  1.441081 0.096880 
7 foo  three 0.296377 1.575791 

Я хочу, чтобы подсчитать, сколько положительных и отрицательных чисел в столбце С принадлежат каждой группе в колонке А и в какой пропорции. В A гораздо больше групп, чем foo и bar, поэтому имена групп не должны быть в коде.

Я пытался группировать A, а затем фильтровать, но не нашел правильный путь. Также пытался объединиться с какой-то умной лямбдой, но не получилось.

ответ

9

Вы можете сделать это в качестве одной линии применяются (первый столбец является отрицательным, вторым положительным):

In [11]: df.groupby('A').C.apply(lambda x: pd.Series([(x < 0).sum(), (x >= 0).sum()])).unstack() 
Out[111]: 
    0 1 
A   
bar 2 1 
foo 2 3 

[2 rows x 2 columns] 

Однако, я думаю, что аккуратнее способ использовать фиктивный столбец и использовать value_counts:

In [21]: df['C_sign'] = np.sign(df.C) 

In [22]: df.groupby('A').C_sign.value_counts() 
Out[22]: 
A  
bar -1 2 
     1 1 
foo 1 3 
    -1 2 
dtype: int64 

In [23]: df.groupby('A').C_sign.value_counts().unstack() 
Out[23]: 
    -1 1 
A   
bar 2 1 
foo 2 3 

[2 rows x 2 columns] 
+2

Я думаю, что предпочитаю 'df [" C_sign "] = np.sign (df.C)'. – DSM

+0

@ DSM согласился, это намного лучше –

Смежные вопросы