Функция агрегации Pandas DataFrame с использованием нескольких столбцов

Есть ли способ написать функцию агрегации, которая используется в методе DataFrame.agg , который будет иметь доступ к нескольким столбцам данных, которые агрегируются? Типичными примерами использования могут быть взвешенные средние взвешенные стандартные отклонения.

Я хотел бы написать что-то вроде

 def wAvg(c, w): return ((c * w).sum() / w.sum()) df = DataFrame(....) # df has columns c and w, i want weighted average # of c using w as weight. df.aggregate ({"c": wAvg}) # and somehow tell it to use w column as weights ... 

5 Solutions collect form web for “Функция агрегации Pandas DataFrame с использованием нескольких столбцов”

Да; используйте .apply(...) , которая будет вызываться на каждом суб- DataFrame . Например:

 grouped = df.groupby(keys) def wavg(group): d = group['data'] w = group['weights'] return (d * w).sum() / w.sum() grouped.apply(wavg) 

Следующее (на основе ответа Wes McKinney) выполняет именно то, что я искал. Я был бы рад узнать, есть ли более простой способ сделать это в pandas .

 def wavg_func(datacol, weightscol): def wavg(group): dd = group[datacol] ww = group[weightscol] * 1.0 return (dd * ww).sum() / ww.sum() return wavg def df_wavg(df, groupbycol, weightscol): grouped = df.groupby(groupbycol) df_ret = grouped.agg({weightscol:sum}) datacols = [cc for cc in df.columns if cc not in [groupbycol, weightscol]] for dcol in datacols: try: wavg_f = wavg_func(dcol, weightscol) df_ret[dcol] = grouped.apply(wavg_f) except TypeError: # handle non-numeric columns df_ret[dcol] = grouped.agg({dcol:min}) return df_ret 

Функция df_wavg() возвращает фрейм данных, сгруппированный столбцом «groupby», и возвращает сумму весов для столбца весов. Другими столбцами являются либо взвешенные средние значения, либо, если они не являются числовыми, для агрегирования используется функция min() .

Я делаю это много и нашел следующее достаточно удобным:

 def weighed_average(grp): return grp._get_numeric_data().multiply(grp['COUNT'], axis=0).sum()/grp['COUNT'].sum() df.groupby('SOME_COL').apply(weighed_average) 

Это вычислит средневзвешенное значение всех числовых столбцов в df и уменьшит числовые.

Выполнение этого с помощью groupby(...).apply(...) не выполняется. Вот решение, которое я использую все время (по существу используя логику Калу).

 def grouped_weighted_average(self, values, weights, *groupby_args, **groupby_kwargs): """ :param values: column(s) to take the average of :param weights_col: column to weight on :param group_args: args to pass into groupby (eg the level you want to group on) :param group_kwargs: kwargs to pass into groupby :return: pandas.Series or pandas.DataFrame """ if isinstance(values, str): values = [values] ss = [] for value_col in values: df = self.copy() prod_name = 'prod_{v}_{w}'.format(v=value_col, w=weights) weights_name = 'weights_{w}'.format(w=weights) df[prod_name] = df[value_col] * df[weights] df[weights_name] = df[weights].where(~df[prod_name].isnull()) df = df.groupby(*groupby_args, **groupby_kwargs).sum() s = df[prod_name] / df[weights_name] s.name = value_col ss.append(s) df = pd.concat(ss, axis=1) if len(ss) > 1 else ss[0] return df pandas.DataFrame.grouped_weighted_average = grouped_weighted_average 

Мое решение похоже на решение Натаниэля, только для одного столбца, и я не делаю глубокое копирование всего кадра данных каждый раз, что может быть непомерно медленным. Увеличение производительности по группе решений (…). Apply (…) составляет около 100x (!)

 def weighted_average(df,data_col,weight_col,by_col): df['_data_times_weight'] = df[data_col]*df[weight_col] df['_weight_where_notnull'] = df[weight_col]*pd.notnull(df[data_col]) g = df.groupby(by_col) result = g['_data_times_weight'].sum() / g['_weight_where_notnull'].sum() del df['_data_times_weight'], df['_weight_where_notnull'] return result 
  • Как функции numpy работают внутри объектов панды?
  • Pandas: Каковы случаи, когда count, возвращаемый DataFrame, описывается как плавающая точка
  • Pandas groupby суммарная сумма
  • Замена значения NaN словом, когда NaN не повторяется в двух последовательных строках
  • Создание нулевого заполненного кадра данных панд
  • pandas: Вычисленный столбец на основе значений в одном столбце
  • Изменение подмножества строк в кадре данных pandas
  • Запустите nltk sent_tokenize через рамку данных Pandas
  • Python - лучший язык программирования в мире.