Группы фильтрации Pandas Dataframe по частоте дат - PullRequest
0 голосов
/ 18 мая 2018

У меня есть фрейм данных pandas со следующими столбцами:

User_id  (numeric)|  Day  (DateTime)|  Data  (numeric)

Я хочу сгруппировать по user_id, чтобы я оставил только тех пользователей, для которых у меня есть Данные, в течение 15 дней подряд..

Скажем, если бы у меня были данные от 01-05 (dd-mm) до 16-05 (dd-mm), строки, относящиеся к этому пользователю, были бы сохранены.

Пример.

df1 = pd.DataFrame(['13-01-2018',1], ['14-01-2018',2],['15-01-2018',3],
        ['13-02-2018',1], ['14-02-2018',2],['15-02-2018',3])

#Apply solution to extract data of first N consecutive dates with N = 3

result.head()

    0                1  
0   13-01-2018       1
1   14-01-2018       2
2   15-01-2018       3

Донне бойтесь спрашивать подробности!Извините, я не могу быть более конкретным.

1 Ответ

0 голосов
/ 03 июня 2018

Мне, наконец, удалось решить эту проблему.

Сначала я подумал, что мои решения не будут оптимальными и займет слишком много времени, но оказалось, что это работает довольно хорошо.

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'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...