Передача процентилей в функцию 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']]
Для указания вашего собственного набора процентилей, выбранный ответ является хорошим выбором, но для простого варианта использования нет необходимости в дополнительных функциях.