Передача процентилей в функцию pandas agg

Я хочу передать функцию numpy percentile() через функцию pandas 'agg(), как показано ниже, с различными другими статистическими функциями numpy.

Прямо сейчас у меня есть dataframe, который выглядит так:

AGGREGATE   MY_COLUMN
A           10
A           12
B           5
B           9
A           84
B           22

И мой код выглядит так:

grouped = dataframe.groupby('AGGREGATE')
column = grouped['MY_COLUMN']
column.agg([np.sum, np.mean, np.std, np.median, np.var, np.min, np.max])

Вышеприведенный код работает, но я хочу сделать что-то вроде

column.agg([np.sum, np.mean, np.percentile(50), np.percentile(95)])

то есть. указать различные процентили для возврата из agg()

Как это сделать?

Ответ 1

Возможно, это не суперэффективно, но одним из способов было бы создать функцию самостоятельно:

def percentile(n):
    def percentile_(x):
        return np.percentile(x, n)
    percentile_.__name__ = 'percentile_%s' % n
    return percentile_

Затем включите это в свой agg:

In [11]: column.agg([np.sum, np.mean, np.std, np.median,
                     np.var, np.min, np.max, percentile(50), percentile(95)])
Out[11]:
           sum       mean        std  median          var  amin  amax  percentile_50  percentile_95
AGGREGATE
A          106  35.333333  42.158431      12  1777.333333    10    84             12           76.8
B           36  12.000000   8.888194       9    79.000000     5    22             12           76.8

Обратите внимание, что это так, как это должно быть сделано, хотя...

Ответ 2

Более конкретно, если вы просто хотите агрегировать свои результаты pandas groupby с использованием функции процентиля, функция лямбда-функции python предлагает довольно аккуратное решение. Используя обозначение вопроса, агрегирование по процентилю 95 должно быть:

dataframe.groupby('AGGREGATE').agg(lambda x: np.percentile(x['COL'], q = 95))

Вы также можете назначить эту функцию переменной и использовать ее в сочетании с другими функциями агрегации.

Ответ 3

Попробуйте это для 50% и 95% процентилей:

column.describe( percentiles = [ 0.5, 0.95 ] )

Ответ 4

Вы можете сделать так, чтобы agg() использовал пользовательскую функцию для выполнения в указанном столбце:

# 50th Percentile
def q50(x):
            return x.quantile(0.5)

# 90th Percentile
def q90(x):
            return x.quantile(0.9)

my_DataFrame.groupby(['AGGREGATE']).agg({'MY_COLUMN': [q50, q90, 'max']})

Ответ 5

Мне очень нравится решение, которое дал Энди Хейден, однако у меня было несколько проблем:

  • Если у фрейма данных есть несколько столбцов, он агрегируется по столбцам, а не по строкам?
  • Для меня имена строк были процентили_0,5 (точка вместо подчеркивания). Не уверен, что вызвало это, вероятно, что я использую Python 3.
  • Нужно также импортировать numpy вместо того, чтобы оставаться в пандах (я знаю, numpy импортируется имплантированно в пандах...)

Вот обновленная версия, которая исправляет эти проблемы:

def percentile(n):
    def percentile_(x):
        return x.quantile(n)
    percentile_.__name__ = 'percentile_{:2.0f}'.format(n*100)
    return percentile_

Ответ 6

Многократная функция может быть вызвана как ниже:

import pandas as pd

import numpy as np

import random

C = ['Ram', 'Ram', 'Shyam', 'Shyam', 'Mahima', 'Ram', 'Ram', 'Shyam', 'Shyam', 'Mahima']

A = [ random.randint(0,100) for i in range(10) ]

B = [ random.randint(0,100) for i in range(10) ]

df = pd.DataFrame({ 'field_A': A, 'field_B': B, 'field_C': C })

print(df)

d = df.groupby('field_C')['field_A'].describe()[['mean', 'count', '25%', '50%', '75%']]
print(d)

Я не смог вызвать медиану в этом, но смог выполнять другие функции.

Ответ 7

В ситуациях, когда все, что вам нужно, это подмножество describe (как правило, наиболее распространенная необходимая статистика), вы можете просто проиндексировать возвращенный ряд панд, не требуя каких-либо дополнительных функций.

Например, мне обычно просто нужно представить 25-е, медиану, 75-е и считать. Это можно сделать одной строкой, например:

columns.agg('describe')[['25%', '50%', '75%', 'count']]

Для указания вашего собственного набора процентилей, выбранный ответ является хорошим выбором, но для простого варианта использования нет необходимости в дополнительных функциях.