Получить средневзвешенное значение нескольких идентификаторов в pandas - PullRequest
0 голосов
/ 06 марта 2020

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

id1         id2       count   average
Person A    class 1   200     0.2
Person A    class 1   400     0.4
Person B    class 2   800     0.6
Person C    class 2   200     0.4
Person B    class 3   800     0.6
Person A    class 4   400     0.2
Person B    class 2   100     0.5

Получает следующий результат (в любом порядке строк):

id1         id2       count   average
Person A    class 1   600     0.33
Person B    class 2   900     0.59
Person C    class 2   200     0.4
Person B    class 3   800     0.6
Person A    class 4   400     0.2

Для справки:

pd.DataFrame({"id1" : ["Person A","Person A","Person B","Person C","Person B","Person A","Person B"],
              "id2" : ["class 1","class 1","class 2","class 2","class 3","class 4","class 2"],
              "count" : [200, 400, 800, 200, 800, 400, 100],
              "average" : [0.2, 0.4, 0.6, 0.4, 0.6, 0.2, 0.5]})

Ответы [ 3 ]

3 голосов
/ 06 марта 2020
df.groupby(['id1','id2']).apply(lambda x: np.average(x.average, weights = x.countx))

Измените имя столбца count как его метод.

3 голосов
/ 06 марта 2020

Использование GroupBy.sum и GroupBy.apply:

df['average'] = df['count'].mul(df['average'])
grps = df.groupby(['id1', 'id2'], sort=False)
g1 = grps['count'].sum()
g2 = grps.apply(lambda x: x['average'].sum() / x['count'].sum())

dfn = pd.concat([g1, g2.rename('average').round(2)], axis=1).reset_index()

        id1      id2  count  average
0  Person A  class 1    600     0.33
1  Person B  class 2    900     0.59
2  Person C  class 2    200     0.40
3  Person B  class 3    800     0.60
4  Person A  class 4    400     0.20
0 голосов
/ 06 марта 2020

Вы можете сначала создать средний столбец, а затем сгруппировать по

df.assign(average=lambda x: x['count'].mul(x['average'])).groupby(['id1', 'id2']).sum().assign(average=lambda x: x['average'] / x['count']).reset_index()

        id1      id2  count   average
0  Person A  class 1    600  0.333333
1  Person A  class 4    400  0.200000
2  Person B  class 2    900  0.588889
3  Person B  class 3    800  0.600000
4  Person C  class 2    200  0.400000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...