Pandas Dataframe根据日期频率过滤组

时间:2018-05-18 19:30:22

标签: python pandas dataframe

我有一个带有下一列的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 :(得分:0)

我终于设法解决了它。

起初我认为我的解决方案不是最优的,而且需要花费太多时间,但结果却很好。

我定义了一个函数,给定n_days时间窗口遍历数据,寻找符合窗口大小(n_days)的delta。因此,它会查找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'])