我有一个带有下一列的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
不要害怕要求进一步的细节!对不起,我不能更具体。
答案 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'])