pandas-группировка и фильтрация последовательных значений
У меня есть этот фрейм данных df:
U,Datetime
01,2015-01-01 20:00:00
01,2015-02-01 20:05:00
01,2015-04-01 21:00:00
01,2015-05-01 22:00:00
01,2015-07-01 22:05:00
02,2015-08-01 20:00:00
02,2015-09-01 21:00:00
02,2014-01-01 23:00:00
02,2014-02-01 22:05:00
02,2015-01-01 20:00:00
02,2014-03-01 21:00:00
03,2015-10-01 20:00:00
03,2015-11-01 21:00:00
03,2015-12-01 23:00:00
03,2015-01-01 22:05:00
03,2015-02-01 20:00:00
03,2015-05-01 21:00:00
03,2014-01-01 20:00:00
03,2014-02-01 21:00:00
Сделано U и Datetime объектом. Что я хотел бы сделать, так это отфильтровать значения U, имеющие по крайней мере три последовательных появления в месяцах/годах. До сих пор я группировался по U, year и month как:
m = df.groupby(['U',df.index.year,df.index.month]).size()
Получение:
U
1 2015 1 1
2 1
4 1
5 1
7 1
2 2014 1 1
2 1
3 1
2015 1 1
8 1
9 1
3 2014 1 1
2 1
2015 1 1
2 1
5 1
10 1
11 1
12 1
Третий столбец связан с событиями, происходящими в разные месяцы/годы. В этом случае только
U значения 02 и 03 содержат по крайней мере три последовательных значения в месяцах/году. Сейчас Я не могу понять, как я могу выбрать этих пользователей и вывести их в список, например, или просто сохранить их в исходном фрейме данных df и отбросить остальные. Я тоже попробовал: g = m.groupby(level=[0,1]).diff()
Но я не могу получить никакой полезной информации.
1 ответ:
Наконец-то я смог придумать решение :) .
Чтобы дать вам представление о том, как работает пользовательская функция, просто вычитает значение месяца из его предыдущего значения, результат должен быть
one, конечно , и это должно произойти дважды , например, если у вас есть список чисел[5 , 6 , 7], так что7 - 6 = 1и6 - 5 = 1,1здесь появился дважды, так что условие было выполненоIn [80]: df.reset_index(inplace=True) In [281]: df['month'] = df.Datetime.dt.month df['year'] = df.Datetime.dt.year df Out[281]: Datetime U month year 0 2015-01-01 20:00:00 1 1 2015 1 2015-02-01 20:05:00 1 2 2015 2 2015-04-01 21:00:00 1 4 2015 3 2015-05-01 22:00:00 1 5 2015 4 2015-07-01 22:05:00 1 7 2015 5 2015-08-01 20:00:00 2 8 2015 6 2015-09-01 21:00:00 2 9 2015 7 2014-01-01 23:00:00 2 1 2014 8 2014-02-01 22:05:00 2 2 2014 9 2015-01-01 20:00:00 2 1 2015 10 2014-03-01 21:00:00 2 3 2014 11 2015-10-01 20:00:00 3 10 2015 12 2015-11-01 21:00:00 3 11 2015 13 2015-12-01 23:00:00 3 12 2015 14 2015-01-01 22:05:00 3 1 2015 15 2015-02-01 20:00:00 3 2 2015 16 2015-05-01 21:00:00 3 5 2015 17 2014-01-01 20:00:00 3 1 2014 18 2014-02-01 21:00:00 3 2 2014 In [284]: g = df.groupby([df['U'] , df.year]) In [86]: res = g.filter(lambda x : is_at_least_three_consec(x['month'].diff().values.tolist())) res Out[86]: Datetime U month year 7 2014-01-01 23:00:00 2 1 2014 8 2014-02-01 22:05:00 2 2 2014 10 2014-03-01 21:00:00 2 3 2014 11 2015-10-01 20:00:00 3 10 2015 12 2015-11-01 21:00:00 3 11 2015 13 2015-12-01 23:00:00 3 12 2015 14 2015-01-01 22:05:00 3 1 2015 15 2015-02-01 20:00:00 3 2 2015 16 2015-05-01 21:00:00 3 5 2015Если вы хотите увидеть результат работы пользовательской функции
In [84]: res = g['month'].agg(lambda x : is_at_least_three_consec(x.diff().values.tolist())) res Out[84]: U year 1 2015 False 2 2014 True 2015 False 3 2014 False 2015 True Name: month, dtype: boolВот как обычай реализованная функция
In [53]: def is_at_least_three_consec(month_diff): consec_count = 0 #print(month_diff) for index , val in enumerate(month_diff): if index != 0 and val == 1: consec_count += 1 if consec_count == 2: return True else: consec_count = 0 return False
Comments