pandas - новая вычисляемая строка для каждой уникальной строки / группы в столбце - PullRequest
0 голосов
/ 03 января 2019

У меня есть фрейм данных df, например:

GROUP  TYPE  COUNT
A       1     5
A       2     10
B       1     3
B       2     9
C       1     20
C       2     100

Я хотел бы добавить строку для каждой группы так, чтобы новая строка вычисляла частное COUNT, где TYPE равно 2 иCOUNT, где TYPE равно 1 для каждого GROUP ala:

GROUP  TYPE  COUNT
A       1     5
A       2     10
A             .5
B       1     3
B       2     9
B             .33
C       1     20
C       2     100
C             .2

Заранее спасибо.

Ответы [ 4 ]

0 голосов
/ 03 января 2019

Вот первый способ использования sort_values' by '['GROUP', 'TYPE'], поэтому TYPE 2 предшествует 1, а затем GroupBy GROUP.

Затем используйте first и last длявычислить фактическое и внешнее объединение с помощью df:

g = df.sort_values(['GROUP', 'TYPE']).groupby('GROUP')
s = (g.first()/ g.nth(1)).COUNT.reset_index()
df.merge(s, on = ['GROUP','COUNT'], how='outer').fillna(' ').sort_values('GROUP')

   GROUP TYPE       COUNT
0     A    1    5.000000
1     A    2   10.000000
6     A         0.500000
2     B    1    3.000000
3     B    2    9.000000
7     B         0.333333
4     C    1   20.000000
5     C    2  100.000000
8     C         0.200000
0 голосов
/ 03 января 2019
df2 = df.pivot(index='GROUP', columns='TYPE', values='COUNT')
df2['div'] = df2[1]/df2[2]
df2.reset_index().melt('GROUP').sort_values('GROUP')

Выход:

  GROUP TYPE       value
0     A    1    5.000000
3     A    2   10.000000
6     A  div    0.500000
1     B    1    3.000000
4     B    2    9.000000
7     B  div    0.333333
2     C    1   20.000000
5     C    2  100.000000
8     C  div    0.200000

Мой подход состоял бы в том, чтобы изменить форму информационного кадра путем поворота, чтобы у каждого типа был свой столбец. Тогда деление очень простое, а затем, плавя, вы возвращаете его к первоначальной форме. На мой взгляд, это тоже очень удобочитаемое решение.

Конечно, если вы предпочитаете от np.nan до div как тип, вы можете заменить его очень легко, но я не уверен, что вы этого хотите.

0 голосов
/ 03 января 2019
s=df[df.TYPE.isin([1,2])].sort_values(['GROUP','TYPE']).groupby('GROUP').COUNT.apply(lambda x : x.iloc[0]/x.iloc[1])
# I am sort and filter your original df ,to make they are ordered and only have type 1 and 2 
pd.concat([df,s.reset_index()]).sort_values('GROUP') 
# cancat your result back 

Out[77]: 
        COUNT GROUP  TYPE
0    5.000000     A   1.0
1   10.000000     A   2.0
0    0.500000     A   NaN
2    3.000000     B   1.0
3    9.000000     B   2.0
1    0.333333     B   NaN
4   20.000000     C   1.0
5  100.000000     C   2.0
2    0.200000     C   NaN
0 голосов
/ 03 января 2019

Вы можете сделать:

import numpy as np
import pandas as pd

def add_quotient(x):
    last_row = x.iloc[-1]
    last_row['COUNT'] = x[x.TYPE == 1].COUNT.min() / x[x.TYPE == 2].COUNT.max()
    last_row['TYPE'] = np.nan
    return x.append(last_row)


print(df.groupby('GROUP').apply(add_quotient))

Вывод

        GROUP  TYPE       COUNT
GROUP                          
A     0     A   1.0    5.000000
      1     A   2.0   10.000000
      1     A   NaN    0.500000
B     2     B   1.0    3.000000
      3     B   2.0    9.000000
      3     B   NaN    0.333333
C     4     C   1.0   20.000000
      5     C   2.0  100.000000
      5     C   NaN    0.200000

Обратите внимание, что функция выбирает минимум TYPE == 1 и максимум TYPE == 2, если в группе более одного значения.И ТИП установлен на np.nan, но это можно легко изменить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...