панда нормализация группы.сум - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть датафрейм панд, который выглядит следующим образом:

      **I     SI     weights**
        1     3      0.3  
        2     4      0.2
        1     3      0.5
        1     5      0.5

Мне нужно сделать это: учитывая значение I, рассмотрите каждое значение SI и добавьте общий вес. В конце я должен иметь для каждой реализации что-то вроде этого:

             I = 1     SI = 3      weight = 0.8
                       SI = 5      weight = 0.5

             I = 2     SI = 4      weight = 0.2

Этого легко добиться, позвонив по групповому номеру и набрав сумму:

       name = ['I', 'SI','weight']
       Location = 'Simulationsdata/prova.csv'
       df = pd.read_csv(Location, names = name,sep='\t',encoding='latin1') 

       results = df.groupby(['I', 'real', 'SI']).weight.sum()

Теперь я хочу, чтобы веса были нормализованы до единицы, чтобы это было примерно так:

             I = 1     SI = 3      weight = 0.615
                       SI = 5      weight = 0.385

             I = 2     SI = 4      weight = 1

Я пробовал это:

        for idx2, j in enumerate(results.index.get_level_values(1).unique()):
            norm = [float(i)/sum(results.loc[j]) for i in results.loc[j]]

но когда я пытаюсь построить для каждого I распределение СИ, я нахожу, что и СИ нормализуются, и я не хочу, чтобы это произошло.

P.s. этот вопрос относится к этому , но поскольку он затрагивает другой аспект проблемы, я подумал, что было бы лучше задать его отдельно

1 Ответ

0 голосов
/ 09 сентября 2018

Вы должны быть в состоянии разделить столбец weight на его собственную сумму:

# example data
df
   I  SI   weight
0  1   3      0.3
1  2   4      0.2
2  1   3      0.5
3  1   5      0.5

# two-level groupby, with the result as a DataFrame instead of Series:
# df['col'] gives a Series, df[['col']] gives a DF
res = df.groupby(['I', 'SI'])[['weight']].sum()
res
       weight
I SI         
1 3       0.8
  5       0.5
2 4       0.2

# Get the sum of weights for each value of I,
# which will serve as denominators in normalization
denom = res.groupby('I')['weight'].sum()
denom
I
1    1.3
2    0.2
Name: weight, dtype: float64

# Divide each result value by its index-matched
# denominator value
res.weight = res.weight / denom
res
        weight
I SI          
1 3   0.615385
  5   0.384615
2 4   1.000000
...