Групповой эквивалент мутаций в пандах / python с использованием принципов тидидаты - PullRequest
1 голос
/ 18 февраля 2020

Мой фрейм данных выглядит следующим образом:

group_var1 = ['A1','A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2', 'A2']
group_var2 = ['B1', 'B1', 'B1', 'B1', 'B2', 'B2', 'B2', 'B2', 'B1', 'B1', 'B1', 'B1', 'B2', 'B2', 'B2', 'B2']
group_var3 = ['C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2', 'C1', 'C2']

value = np.arange(len(group_var1))

ex_df = pd.DataFrame({
    'group_var1' : group_var1,
    'group_var2' : group_var2,
    'group_var3' : group_var3,
    'value' : value
})

, который должен вызывать следующее при вызове:

    group_va1   group_va2   group_va3   value
0   A1  B1  C1  0
1   A1  B1  C2  1
2   A1  B1  C1  2
3   A1  B1  C2  3
4   A1  B2  C1  4
5   A1  B2  C2  5
6   A1  B2  C1  6
7   A1  B2  C2  7
8   A2  B1  C1  8
9   A2  B1  C2  9
10  A2  B1  C1  10
11  A2  B1  C2  11
12  A2  B2  C1  12
13  A2  B2  C2  13
14  A2  B2  C1  14
15  A2  B2  C2  15

Моя цель - сгруппировать фрейм данных по столбцам group_var1, group_var2 и group_var3, а затем вычислите среднее значение value в каждой группе и добавьте новую строку mean_ex в этот существующий DataFrame с этими результатами. В R это может быть выполнено с помощью ex_df %>% group_by(c(group_var1, group_var2, group_var3)) %>% mutate(mean_ex = mean(value)), который автоматически обрабатывает присвоение нового значения соответствующим строкам.

Я нашел способы суммировать DataFrame, объединяя все значения в каждой группе только в среднее значение (ex_df.groupby(['group_var1', 'group_var2', 'group_var3']).mean()), но я хочу, чтобы среднее значение было новым столбцом в моем существующем DataFrame, не df меньших размеров. Мой желаемый результат может быть найден ниже, и был достигнут с помощью pd.merge () на моем исходном df и моей ранее описанной нежелательной агрегированной таблице:


    group_var1  group_var2  group_var3  value   mean_ex
0   A1  B1  C1  0   1
1   A1  B1  C2  1   2
2   A1  B1  C1  2   1
3   A1  B1  C2  3   2
4   A1  B2  C1  4   5
5   A1  B2  C2  5   6
6   A1  B2  C1  6   5
7   A1  B2  C2  7   6
8   A2  B1  C1  8   9
9   A2  B1  C2  9   10
10  A2  B1  C1  10  9
11  A2  B1  C2  11  10
12  A2  B2  C1  12  13
13  A2  B2  C2  13  14
14  A2  B2  C1  14  13
15  A2  B2  C2  15  14

Мой вопрос заключается в том, есть ли способ достичь этого желаемый результат без необходимости создавать отдельный фрейм данных, который затем объединяется с оригиналом? Спасибо.

1 Ответ

0 голосов
/ 18 февраля 2020

Используйте transform и assign:

ex_df.assign(
    mean_val = 
    ex_df
    .groupby(["group_var1", "group_var2",  "group_var3"])
    .value
    .transform('mean')
)

   group_var1 group_var2 group_var3  value  mean_val
0          A1         B1         C1      0         1
1          A1         B1         C2      1         2
2          A1         B1         C1      2         1
3          A1         B1         C2      3         2
4          A1         B2         C1      4         5
5          A1         B2         C2      5         6
6          A1         B2         C1      6         5
7          A1         B2         C2      7         6
8          A2         B1         C1      8         9
9          A2         B1         C2      9        10
10         A2         B1         C1     10         9
11         A2         B1         C2     11        10
12         A2         B2         C1     12        13
13         A2         B2         C2     13        14
14         A2         B2         C1     14        13
15         A2         B2         C2     15        14

Пояснение
Pandas assign - это грубый эквивалент dplyr::mutate, и transform транслирует операцию группировки по всем начальным строкам ввода, а не просто вызывает функцию агрегирования после groupby.

Что-то вроде df.groupby('a').x.mean() приведет к одному значению для каждого сгруппированного индекса, который является аналогом dplyr::summarise.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...