Фильтрация выбросов перед использованием группировки по - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть фрейм данных со столбцом цены (p), и у меня есть некоторые нежелательные значения, такие как (0, 1,50, 92,80, 0,80).Прежде чем рассчитать среднее значение цены по коду продукта, я бы хотел удалить эти выбросы

                Code    Year    Month  Day   Q      P
0               100     2017       1    4   2.0  42.90
1               100     2017       1    9   2.0  42.90
2               100     2017       1   18   1.0  45.05
3               100     2017       1   19   2.0  45.05
4               100     2017       1   20   1.0  45.05
5               100     2017       1   24  10.0  46.40
6               100     2017       1   26   1.0  46.40
7               100     2017       1   28   2.0  92.80
8               100     2017       2    1   0.0   0.00
9               100     2017       2    7   2.0   1.50
10              100     2017       2    8   5.0   0.80
11              100     2017       2    9   1.0  45.05
12              100     2017       2   11   1.0   1.50
13              100     2017       3    8   1.0  49.90
14              100     2017       3   17   6.0  45.05
15              100     2017       3   24   1.0  45.05
16              100     2017       3   30   2.0   1.50

Как было бы хорошим способом отфильтровать выбросы для каждого продукта (сгруппировать по коду)?

Я пробовал это:

stds = 1.0  # Number of standard deviation that defines 'outlier'.
z = df[['Code','P']].groupby('Code').transform(
    lambda group: (group - group.mean()).div(group.std()))
outliers = z.abs() > stds
df[outliers.any(axis=1)]

А потом:

print(df[['Code', 'Year', 'Month','P']].groupby(['Code', 'Year', 'Month']).mean())

Но фильтр выбросов не работает должным образом.

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

У вас правильная идея.Просто возьмите булеву противоположность вашей серии outliers['P'] через ~ и отфильтруйте ваш фрейм данных через loc:

res = df.loc[~outliers['P']]\
        .groupby(['Code', 'Year', 'Month'], as_index=False)['P'].mean()

print(res)

   Code  Year  Month          P
0   100  2017      1  44.821429
1   100  2017      2  45.050000
2   100  2017      3  46.666667
0 голосов
/ 21 ноября 2018

IIUC Вы можете использовать групповой режим на Code, рассчитать z для P и отфильтровать, если z превышает ваш порог:

stds = 1.0 
filtered_ df = df[~df.groupby('Code')['P'].transform(lambda x: abs((x-x.mean()) / x.std()) > stds)]

    Code  Year  Month  Day     Q      P
0    100  2017      1    4   2.0  42.90
1    100  2017      1    9   2.0  42.90
2    100  2017      1   18   1.0  45.05
3    100  2017      1   19   2.0  45.05
4    100  2017      1   20   1.0  45.05
5    100  2017      1   24  10.0  46.40
6    100  2017      1   26   1.0  46.40
11   100  2017      2    9   1.0  45.05
13   100  2017      3    8   1.0  49.90
14   100  2017      3   17   6.0  45.05
15   100  2017      3   24   1.0  45.05

filtered_df[['Code', 'Year', 'Month','P']].groupby(['Code', 'Year', 'Month']).mean()
                     P
Code Year Month           
100  2017 1      44.821429
          2      45.050000
          3      46.666667
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...