python / pandas эквивалент dplyr 1.0.0 summarize (через ()) - PullRequest
2 голосов
/ 01 августа 2020

В R я считаю очень полезным следующее при работе со многими переменными:

library(dplyr)
dat <- group_by(mtcars, cyl) 
summarize(dat, across(c('mpg','disp'), sum), across(c('drat','wt','qsec'), mean))
# A tibble: 3 x 5
    cyl  disp    hp  drat    wt
  <dbl> <dbl> <dbl> <dbl> <dbl>
1     4 1156.   909  4.07  2.29
2     6 1283.   856  3.59  3.12
3     8 4943.  2929  3.23  4.00

Или, что еще лучше, выбор с помощью псевдо-регулярного выражения

summarize(dat, across(ends_with('p'), sum), across(ends_with('t'), mean))

В pandas, эквивалент, похоже, передает переменные одну за другой в словарь, например из this gist :

group_agg = df.groupby("group1").agg({
  "var1" : ["mean"], 
  "var2" : ["sum"], 
  "var3" : ["mean"]
  })

Есть ли менее подробный способ выполнить эту операцию в pandas, или с другим пакетом?

Ответы [ 2 ]

3 голосов
/ 01 августа 2020

Предполагая, что вы хотите это для широкого фрейма данных с множеством целевых столбцов агрегации, понимание словаря может имитировать c регулярное выражение:

group_agg = df.groupby('group1').agg(
    {var: 'sum' if var[-1]=='p' else 'mean' for var in cols})

В общем, вы можете построить понимание dict с другими условиями, такими как dtypes, str в строке, количество шаблонов регулярных выражений и т.д. c.

2 голосов
/ 01 августа 2020

Для первого сценария достаточно pandas concat:

dat = df.groupby("cyl")

pd.concat([dat[["mpg", "disp"]].sum(), dat[["drat", "wt", "qsec"]].mean()], axis=1)

Для части обработки регулярных выражений / строк многословность неизбежна:

cols_p = [col for col in df.columns if col.endswith("p")]
cols_t = [col for col in df.columns if col.endswith("t")]

pd.concat((dat[cols_p].sum(), dat[cols_t].mean()), axis=1)

Было бы круто, если бы вы могли бы написать функцию, которая могла бы инкапсулировать across, особенно для regex - это прекрасный прекрасный трюк.

Примечание: передача словаря не длиннее и не более подробна, чем первый пример, который вы процитировали. Я бы посоветовал по методу pandas concat:

dat.agg({"mpg": "sum", 
         "disp": "sum", 
         "drat": "mean", 
         "wt": "mean", 
         "qsec": "mean"})

Не убирает блеск с across -> выглядит круто.

Обновить : Для части регулярного выражения / строки, взяв реплику из сообщения @ Richiev , понимание словаря здесь очень хорошо вписывается:

df.groupby('cyl').agg({col :'mean'
                       if col.endswith('t') 
                       else 'sum' 
                       for col in df.filter(regex=r".*(p|t)$").columns
                      })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...