Преобразование, чтобы показать среднее значение, st.dev из набора данных в python

#python #pandas #numpy

#python #pandas #numpy

Вопрос:

У меня есть набор данных, df, где я хотел бы показать сравнения среднего и среднего отклонения по группам, сохраняя при этом столбцы id, start, end и value в выходных данных.

 id  start       end         value

a   5/1/2020    6/1/2020    2
a   6/1/2020    7/1/2020    3
a   7/1/2020    8/1/2020    4
a   8/1/2020    9/1/2020    20
b   5/1/2020    6/1/2020    15
b   6/1/2020    7/1/2020    2
b   7/1/2020    8/1/2020    1
  

Желаемый результат

 id  start       end         value   mean    stdev       1SD       2SD     3SD

a   5/1/2020    6/1/2020    2                   
a   6/1/2020    7/1/2020    3                   
a   7/1/2020    8/1/2020    4                   
a   8/1/2020    9/1/2020    20      29      8.539126    20.5      12     -5.5
b   5/1/2020    6/1/2020    15                  
b   6/1/2020    7/1/2020    2                   
b   7/1/2020    8/1/2020    1       18      7.81025     10.2      2.4    -5.4
  

Желаемый результат, группирует идентификатор, а также значение и находит среднее
значение, стандартное отклонение и 1SD, 2SD и 3SD

Это то, что я делаю:

 df = pd.read_csv("data.csv")

output = df.groupby('id')['value'].agg(['mean','std'])   

output['1SD'] = output['mean'] - output['std']              

output['2SD'] = output['mean'] - 2 *output['std']           

output['3SD'] = out['mean'] - 3 *output['std']    
  

Однако мне не удалось сохранить столбцы start, end и value. Я все еще занимаюсь исследованиями, и любое
предложение приветствуется.

Ответ №1:

Используйте GroupBy.transform здесь:

 g = output.groupby('id')['value']
output['mean'] = g.transform('mean')   
output['std'] = g.transform('std')

output['1SD'] = output['mean'] - output['std']              
output['2SD'] = output['mean'] - 2 *output['std']           
output['3SD'] = out['mean'] - 3 *output['std']    
  

Если требуется только одна строка на группу, добавьте Series.duplicated для сопоставления только последние дублированные строки:

 mask = ~df['id'].duplicated(keep='last')
g = output.groupby('id')['value']
output.loc[mask, 'mean'] = g.transform('mean')   
output.loc[mask, 'std'] = g.transform('std')

output['1SD'] = output['mean'] - output['std']              
output['2SD'] = output['mean'] - 2 *output['std']           
output['3SD'] = output['mean'] - 3 *output['std']    

print (output)
  id     start       end  value  mean       std       1SD       2SD        3SD
0  a  5/1/2020  6/1/2020      2   NaN       NaN       NaN       NaN        NaN
1  a  6/1/2020  7/1/2020      3   NaN       NaN       NaN       NaN        NaN
2  a  7/1/2020  8/1/2020      4   NaN       NaN       NaN       NaN        NaN
3  a  8/1/2020  9/1/2020     20  7.25  8.539126 -1.289126 -9.828251 -18.367377
4  b  5/1/2020  6/1/2020     15   NaN       NaN       NaN       NaN        NaN
5  b  6/1/2020  7/1/2020      2   NaN       NaN       NaN       NaN        NaN
6  b  7/1/2020  8/1/2020      1  6.00  7.810250 -1.810250 -9.620499 -17.430749
  

Комментарии:

1. Привет @jezrael, я попробую это. Не могли бы вы объяснить, что делает ‘маска’?

2. @Lynnette — он присваивает строки только для последней строки для групп, если опустить его, повторяются все значения для групп, другими словами, нет NAN, как во втором решении.