фильтрация панд после группового режима с условиями фильтра groupby-specc? - PullRequest
1 голос
/ 07 марта 2019

Я видел множество отличных решений для «фильтрации по группам», в которых условие фильтра является фиксированным («эй, группируйте по имени, а затем ищите всех в возрасте старше 21 года», где 21 исправлено. I Вместо этого я ищу способ фильтрации на основе результатов группового.

пример:

df = pd.DataFrame({'person':['Sue', 'Sue', 'Sue', 'Bill', 'Alfonso'],
               'date': ['2019-01-01','2019-01-02', '2019-01-03','2019-02-01', '2019-03-01'],
               'my_value': [5,10,20,10,5],
               'my_other_value': [3,2,9,6,8]})

Я хочу иметь возможность задать вопрос по следующим направлениям: «начиная с первого раза, когда у человека my_value равно 10, скажите мне среднее значение my_other_value для всех последовательных записей».

В этом примере первая дата, в которой у Сью my_value == 10, это 2019-01-02, поэтому ее среднее значение для my_other_value равно (2 + 9) / 2 = 5,5, что происходит с 2019-01-02. и 2019-01-03. У Билла есть только одна запись, но он имеет значение my_value, равное 10, поэтому его среднее значение my_other_value равно 6. К сожалению, у Альфонсо никогда нет значения my_value, равного 10, поэтому он даже не включен в итоговый подсчет

Итак, я начал с

df2 = df.query('my_value == 10').groupby('person').first().reset_index()

, который получает мой первый раз, когда у человека my_value = 10. Из этого я знаю человека и дату, когда это произошло. Итак, на английском я хочу отфильтровать эти результаты для этого человека, чтобы я мог сделать .mean (), но только с учетом строк для этого человека> = дата, которую я узнал из вызова first (). Я застрял, конечно.

Я вроде как надеялся, что что-то подобное сработает:

df3 = df.groupby('person').apply( lambda x: x['date'] >= df2['date']).mean()

но я знаю, что это не может действительно работать, потому что как лямбда знает, как сопоставить правильного человека в df.groupby () с тем же человеком в группе df2?

Другой вариант заключался в том, чтобы подумать: «эй, может быть, есть версия расширения (), которая может начинаться с чего-то другого, кроме самой первой записи»

Скрестив пальцы, что один из вышеперечисленных подходов направлен правильно, и появляется какой-то герой, чтобы сказать: «О, вы так близки, просто добавьте эту маленькую дополнительную часть!»

1 Ответ

0 голосов
/ 07 марта 2019

«о, вы так близки, просто добавьте эту небольшую дополнительную часть!»

См. Ниже небольшую дополнительную часть.

df = pd.DataFrame({'person':['Sue', 'Sue', 'Sue', 'Bill', 'Alfonso'],
               'date': ['2019-01-01','2019-01-02', '2019-01-03','2019-02-01', '2019-03-01'],
               'my_value': [5,10,20,10,5],
               'my_other_value': [3,2,9,6,8]})
df = df.sort_values(['person', 'date']).reset_index(drop=True)

>>> df

    person  date        my_value    my_other_value
0   Alfonso 2019-03-01  5           8
1   Bill    2019-02-01  10          6
2   Sue     2019-01-01  5           3
3   Sue     2019-01-02  10          2
4   Sue     2019-01-03  20          9

Найти первую дату my_value == 10

df2 = df.query('my_value == 10').groupby('person').first()['date'].reset_index()
df2 = df2.rename(columns={'date': 'first_date'})
>>> df2

    person  first_date
0   Bill    2019-02-01
1   Sue     2019-01-02

Объединить фреймы данных

df_merged = pd.merge(df, df2, how='left', on=['person'])
>>> df_merged

    person  date        my_value    my_other_value  first_date
0   Alfonso 2019-03-01  5           8               NaN
1   Bill    2019-02-01  10          6               2019-02-01
2   Sue     2019-01-01  5           3               2019-01-02
3   Sue     2019-01-02  10          2               2019-01-02
4   Sue     2019-01-03  20          9               2019-01-02

Рассчитать среднее значение my_other_value

grouped = df_merged[df_merged['date'] >= df_merged['first_date']].groupby('person')
>>> grouped['my_other_value'].mean()

person
Bill    6.0
Sue     5.5
Name: my_other_value, dtype: float64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...