У меня есть очень большой пандан DataFrame с несколькими тысячами кодов и стоимостью, связанной с каждым из них (пример):
data = {'code': ['a', 'b', 'a', 'c', 'c', 'c', 'c'],
'cost': [10, 20, 100, 10, 10, 500, 10]}
df = pd.DataFrame(data)
Я создаю groupby
объект на уровне code
, т. е.:
grouped = df.groupby('code')['cost'].agg(['sum', 'mean']).apply(pd.Series)
Теперь мне действительно нужно добавить новый столбец в этот grouped
DataFrame, определяющий процент кодов, которые имеют затраты на выбросы.Мой первоначальный подход был такой внешней функцией (используя iqr
из scipy
):
def is_outlier(s):
# Only calculate outliers when we have more than 100 observations
if s.count() >= 100:
return np.where(s >= s.quantile(0.75) + 1.5 * iqr(s), 1, 0).mean()
else:
return np.nan
Написав эту функцию, я добавил is_outlier
к своим agg
аргументам в groupby
выше.Это не сработало, потому что я пытаюсь оценить этот коэффициент is_outlier
для каждого элемента в серии cost
:
grouped = df.groupby('code')['cost'].agg(['sum', 'mean', is_outlier]).apply(pd.Series)
Я пытался использовать pd.Series.where
, но он не имеет такой же функциональностикак np.where
.Есть ли способ изменить мою функцию is_outlier
, которая должна принимать ряд cost
в качестве аргумента, чтобы правильно оценить уровень выбросов для каждого кода?Или я совершенно не в курсе?
ОБНОВЛЕНИЕ Желаемый результат (минус минимальное требование к наблюдениям для этого примера):
>>> grouped
code sum mean is_outlier
0 'a' 110 55 0.5
1 'b' 20 20 0
2 'c' 530 132.5 0.25
Примечание: мой образец ужасен вдля меня, чтобы рассчитать выбросы, так как у меня есть 2, 1 и 4 наблюдения соответственно для каждого code
.В производственном фрейме данных каждый код имеет сотни или тысячи наблюдений, каждое из которых связано со стоимостью.В приведенном выше примере выборки значения для is_outlier
означают, что для 'a'
одно из двух наблюдений имеет стоимость в диапазоне выбросов, для 'c'
одно из четырех наблюдений имеет стоимость в диапазоне выбросови т. д. - я пытаюсь воссоздать это в своей функции, присваивая 1 и 0 в результате np.where()
и получая .mean()
из этого
.apply(pd.Series)
, необходимого для приведения <pandas.core.groupby.SeriesGroupBy object> resulting from
groupby into a DataFrame.
s is a pandas Series with all values of
стоимость for each
код , as generated from the
groupby operation (
split phase of
split-apply-Объединить`)