Как сделать среднюю относительную ошибку для разных групп после groupby?

Я делаю проект, который имеет дело с большим набором данных. Однако теперь я хотел сделать простое сравнение, и я не могу найти, как я могу это сделать. Проще говоря, к более простой проблеме, моя проблема заключается в следующем. У меня есть 3 разных столбца и 6 строк:

A   B   C
g   1   2 
h   2   1
j   3   3
h   3   3
g   4   3
j   5   4

Первое, что я хотел сделать, это рассчитать среднее, медиану и моду B с учетом группы A. Итак, я сделал так, и пока все хорошо:

aggregations_proc = {'C': { 'Mean_proc': 'mean', 'Median_proc': 'median',
                                  'Mode_proc': lambda x: x.mode()}}
groupy_proc = df.groupby('A', as_index=False).agg(aggregations_proc)

Однако теперь моей целью было просто создать новый столбец, представляющий расчет средней относительной ошибки для каждой из строк между B и средним значением C, учитывая, что среднее значение варьируется для каждой группы. Например, для первой строки относительная ошибка будет следующей: (Среднее значение группы g — значение B 1-й строки) / Среднее значение группы g. Однако для второй строки это уже будет (Среднее значение группы h — значение B 2-й строки) / Среднее значение группы h И для 3-й строки (среднее значение группы j — значение B 3-й строки) / среднее значение группы j Но это относится к гораздо большему набору данных.

Любая помощь будет очень кстати!

[ОБНОВИТЬ]

Вот мой новый код. Я думаю, что все работает, но я предполагаю, что есть какая-то ошибка в режиме. Ошибка: «Столбцы должны быть той же длины, что и ключ». Код следующий:

aggregations_diag = ('mean', 'median', lambda x: x.mode().iloc[0])
groupy_diag = df.groupby('A', as_index=False) 
['B'].agg(aggregations_diag) 

def absolute_error_diag(x): 
stats = ['mean', 'median', lambda x: x.mode().iloc[0]]
avg = groupy_diag.loc[x['A'], stats] 
return (avg - x['B'])

# Columns for the absolute error of each row
columns_names_diag = ['ae_diag_mean','ae_diag_median','ae_diag_mode']

df[columns_names_diag] = df.apply(absolute_error_diag, axis=1)

[MAE_diag_mean, MAE_diag_median, MAE_diag_mode] = 
df[columns_names_diag].sum()/len(df['ae_diag_mean'])

person bonaqua    schedule 14.01.2020    source источник
comment
Может помочь, если вы создадите еще одну диаграмму того, как вы хотите, чтобы она выглядела, потому что у меня возникают проблемы с визуализацией конечного продукта.   -  person Petar Luketina    schedule 15.01.2020


Ответы (1)


Функция aggregations_proc в вопросе не выполняет агрегирование по столбцу B. Одним из способов агрегации может быть:

aggregations_proc = ('mean', 'median', lambda x: x.mode().iloc[0])
groupy_proc = df.groupby('A', as_index=False)['B'].agg(aggregations_proc) 

Несмотря на это, apply() можно использовать в сочетании с df и groupy_proc. Функция для расчета средней относительной ошибки может быть:

def mean_rel_error(x): # x is a row of df
    avg = groupy_proc.loc[x['A'], 'mean'] # to find avg, locate 'mean' col in the row corresponding to the value of col A 
    return (avg - x['B']) / avg

Вызов функции будет выглядеть так:

df['mre'] = df.apply(mean_rel_error, axis=1)

Надеюсь это поможет. Для большей эффективности вы можете рассмотреть возможность создания словаря только средних значений и изменить функцию mean_rel_error()


ОБНОВИТЬ:

Вот код для расчета средней абсолютной ошибки, которая сработала для меня:

l = [["g",1,5], ["h",2,2], ["j",3,9], ["g",3,5], ["j",4,3], ["h",5,1], ["g",11,1]]
df = pd.DataFrame(l, columns=["A", "B", "C"])

aggregations_proc = ('mean', 'median', lambda x: x.mode().iloc[0])
groupy_proc = df.groupby('A', as_index=False)['B'].agg(aggregations_proc)
groupy_proc.columns = ['mean', 'median', 'mode']


def mean_rel_error(x):
    stats = ['mean', 'median', 'mode']
    avg = groupy_proc.loc[x['A'], stats] 
    return (avg - x['B'])

columns_names_diag = ['ae_diag_mean','ae_diag_median','ae_diag_mode']

df[columns_names_diag] = df.apply(mean_rel_error, axis=1)
[MAE_diag_mean, MAE_diag_median, MAE_diag_mode] = df[columns_names_diag].sum()/len(df['ae_diag_mean'])


print(MAE_diag_mode)
-> -2.2857142857142856
person S.Au.Ra.B.H    schedule 15.01.2020
comment
О, да! Я полностью понял! Большое спасибо за помощь, правда! Только один вопрос, для чего нужен словарь? - person bonaqua; 15.01.2020
comment
Словарь @bonaqua для хранения средств, предназначенный для более быстрого поиска. Это может быть формат {x:mean(x)}, где x — элемент столбца A. - person S.Au.Ra.B.H; 15.01.2020
comment
@bonaqua это ответ на твой вопрос? Если да, пожалуйста, не стесняйтесь принять ответ! Ваше здоровье! - person S.Au.Ra.B.H; 16.01.2020
comment
Я обновил свой вопрос новым кодом! Однако теперь у меня есть ошибка. Я не знаю, сможете ли вы мне помочь, но вы не знаете, почему это неправильно? - person bonaqua; 21.01.2020
comment
@bonaqua Я не вижу ничего плохого в коде, кроме stats = ['mean', 'median', lambda x: x.mode().iloc[0]]. Попробуйте переименовать последний столбец groupy_diag в подходящее имя, например mode, и используйте это имя вместо лямбда-функции в функции absolute_error_diag(). Таким образом, новое задание будет выглядеть так: stats = ['mean', 'median', 'mode'] - person S.Au.Ra.B.H; 21.01.2020
comment
если я переключаюсь на режим, он работает, но почему бы мне не использовать лямбду x: x.mode.iloc[0]? Если я использую режим, MAE_diag_mode будет равен нулю. Поэтому я думаю, что что-то может быть не так - person bonaqua; 21.01.2020
comment
@bonaqua Использование лямбда-функции в назначении статистики создавало дополнительные столбцы, когда я пытался запустить измененный код. Кроме того, MAE_diag_mode вернул ненулевые значения. Смотрите обновленный ответ. - person S.Au.Ra.B.H; 22.01.2020