Python Расчет по группам - PullRequest
1 голос
/ 03 июня 2019

У меня есть данные:

print(dataset)
variable   groups    value  
    Both        I  3099060    
    Both        U   175820    
    C_only      I  5207055    
    C_only      U   225992    
    P_only      I  4063438    
    P_only      U   175593    
      None      I  9413116    
      None      U   292982    

dataset.value.dtype
dtype('int64')
type(dataset)
pandas.core.frame.DataFrame

Я пытаюсь создать новую переменную с именем value2, которая рассчитывается по значению, деленному на общее значение по каждой группе.
ЧтоЯ хочу:

variable   groups    value     value2
    Both        I  3099060    0.14227
    Both        U   175820    0.20200
    C_only      I  5207055    0.23905
    C_only      U   225992    0.25965
    P_only      I  4063438    0.18654
    P_only      U   175593    0.20174
      None      I  9413116    0.43214
      None      U   292982    0.33661

Я использовал groupby для расчета, но получил NaN:

dataset['value2'] = dataset.groupby(['groups']).value / dataset.groupby(['groups']).value.sum()  

Любое предложение?

Ответы [ 2 ]

3 голосов
/ 03 июня 2019

Используйте groupby + transform, чтобы создать массив такой же формы, как ваш столбец values, таким образом, вы можете просто разделить оба:

df['value2'] = df['value'] / df.groupby('groups')['value'].transform('sum')

Или

Мы можем использовать div метод

df['value2'] = df['value'].div(df.groupby('groups')['value'].transform('sum'))

  variable groups    value    value2
0     Both      I  3099060  0.142272
1     Both      U   175820  0.202002
2   C_only      I  5207055  0.239046
3   C_only      U   225992  0.259645
4   P_only      I  4063438  0.186545
5   P_only      U   175593  0.201741
6     None      I  9413116  0.432138
7     None      U   292982  0.336611

Сравнение скорости

dfbig = pd.concat([df]*100000)
dfbig.shape

(800000, 4)

Erfan 1

%%timeit

dfbig['value2'] = dfbig['value'] / dfbig.groupby('groups')['value'].transform('sum')

109 ms ± 8.92 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

Erfan 2

%%timeit

dfbig['value2'] = dfbig['value'].div(dfbig.groupby('groups')['value'].transform('sum'))

113 ms ± 2.96 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

iamchoosinganame

%%timeit

dfbig['value2']=dfbig.groupby('groups')['value'].transform(lambda x: x/x.sum())

412 ms ± 12.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
1 голос
/ 03 июня 2019

Использование группировки и преобразования с помощью лямбда-функции.

dataset['value2']=dataset.groupby('groups')['value'].transform(lambda x: x/x.sum())
...