Мне, наконец, удалось решить эту проблему.
Сначала я подумал, что мои решения не будут оптимальными и займет слишком много времени, но оказалось, что это работает довольно хорошо.
Iопределил функцию, которая с учетом временного окна n_days обходит данные в поисках дельты, соответствующей размеру окна (n_days).Таким образом, он ищет n_days последовательных дат.
def consecutive(x,n_days):
result = None
if len(x) >= n_days:
stop = False
i = n_days
while(stop == False and i < len(x)+1):
window = lista[i-n_days:i]
delta = (window[len(window)-1]-window[0]).n_days
if delta == n_days-1:
stop = True
result = window
i=i+1
return result
И затем вызывает его с помощью apply.
b=a.groupby('user_id')['day'].unique().apply(lambda x: consecutive(x,15))
df=b.loc[b.apply(lambda x: x is not None)].reset_index()
Следующие шаги подразумевают преобразование кадра данных в один со строкой на возвращаемое значение.дата.
import itertools
import pandas as pd
import numpy as np
def melt_series(s):
lengths = s.str.len().values
flat = [i for i in itertools.chain.from_iterable(s.values.tolist())]
idx = np.repeat(s.index.values, lengths)
return pd.Series(flat, idx, name=s.name)
df=melt_series(df.day).to_frame().join(df.drop('day', 1)).reindex_axis(df.columns, 1)
и объединение с фактическим фреймом данных.
final =pd.merge(a,df[['user_id','day']],on=['user_id','day'])