Применение функции взвешенного среднего к столбцу в объекте pandas groupby, но весовая сумма равна нулю - PullRequest
1 голос
/ 12 апреля 2019

Я применяю разные функции к каждому столбцу в объекте группового панды. Одной из этих функций является взвешенное среднее, где весами являются связанные значения в другом столбце в кадре данных. Тем не менее, для ряда моих групп веса суммируются до нуля. Из-за этого при запуске кода появляется сообщение об ошибке «Сумма весов к нулю, нормализация невозможна».

Обращаясь к приведенному ниже коду, для группы, определенной значением col1 x и значением col2 y, сумма значений в col3 в строках с col1 = x и col2 = y равна нулю, создавая ошибку в средневзвешенном значении col5.

Есть ли способ сделать так, чтобы группы, для которых веса суммировались в ноль, возвращали «средневзвешенное» значение нуля? Спасибо!

df = pd.DataFrame([['x','x','x','y','y','y'],['a','a','b','b','c','c'],
                   [0,0,3,4,5,6],[1,1,1,1,1,1],[0,0,4,6,2,8]],
                   ).transpose()
df.columns = ['col1','col2','col3','col4','col5']

weighted_average = lambda x: np.average(x, weights=df.loc[x.index, 'col3'])
averages = df.groupby(['col1','col2']).agg({'col3':'sum', 
                               'col4':'sum', 
                               'col5': weighted_average})

1 Ответ

0 голосов
/ 12 апреля 2019

Мы можем сделать следующее:

  • Напишите нашу собственную функцию, чтобы проверить, есть ли 0 в col3 и col5.Иначе возьмите средневзвешенное значение.
  • Констатируйте агрегацию sum без средневзвешенного значения
def weighted_average(x):
    if (x.col3 > 0).all() & (x.col5 > 0).all():
        return np.average(x.col5, weights=x.col3)
    else:
        return 0


averages = df.groupby(['col1','col2']).agg({'col3':'sum', 
                                            'col4':'sum'})

weighted_avg = df.groupby(['col1','col2']).apply(weighted_average)

df_averages = pd.concat([averages, weighted_avg ], axis=1)\
                .reset_index()\
                .rename({0:'col5'}, axis=1)

Что дает:

print(df_averages)
           col3  col4      col5
col1 col2                      
x    a        0     2  0.000000
     b        3     1  4.000000
y    b        4     1  6.000000
     c       11     2  5.272727
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...