假设我有包含usersidid(int)和date(datatime)的df:
usersidid date
1 1 2017-01-05
2 2 2017-01-02
3 3 2017-01-04
4 4 2017-01-02
5 1 2017-01-01
6 2 2017-01-03
7 3 2017-01-02
8 1 2017-01-04
9 2 2017-01-05
我有@timeframe,@ MinDates的参数。 我需要检查每个用户ID ,如果从今天到今天(@timeframe),数据帧中有足够的不同MinDates,如果不是程序需要退出。我会说:
示例A -
@timeframe = 5
@MinDates = 1
today = 2017-01-05
在这种情况下结果:
usersidid date
1 1 2017-01-01
2 1 2017-01-04
3 1 2017-01-05
4 2 2017-01-02
5 2 2017-01-03
6 2 2017-01-05
7 3 2017-01-02
8 3 2017-01-04
9 4 2017-01-02
示例B -
@timeframe = 5
@MinDates = 2
today = 2017-01-05
在这种情况下结果:
usersidid date
1 1 2017-01-01
2 1 2017-01-04
3 1 2017-01-05
4 2 2017-01-02
5 2 2017-01-03
6 2 2017-01-05
7 3 2017-01-02
8 3 2017-01-04
示例C -
@timeframe = 5
@MinDates = 3
today = 2017-01-05
在这种情况下结果:
usersidid date
1 1 2017-01-01
2 1 2017-01-04
3 1 2017-01-05
4 2 2017-01-02
5 2 2017-01-03
6 2 2017-01-05
示例D -
@timeframe = 5
@MinDates = 4
today = 2017-01-05
在这种情况下结果:在时间范围内没有足够的不同日期,退出程序
示例E -
@timeframe = 3
@MinDates = 2
today = 2017-01-05
在这种情况下结果(由Ted Petrou修复):
usersidid date
1 1 2017-01-04
2 1 2017-01-05
3 2 2017-01-03
4 2 2017-01-05
我的想法一般:
agg1 = df[today >= timedelta(days=@dataframe) + df.date]
agg2 = agg1.groupby(['usersidid'], as_index=False, sort=False)['date'].countunique().rename(columns={'date': 'NumOfDifferentDates'})
agg3 = agg2[agg2.NumOfDifferentDates >= @MinDates]
result = df[df.usersidid.isin(agg3.loc[:, 'usersidid'])].reset_index(drop=True)]
if result.empty() exit(0)
我还没有运行它所以我不知道它是否有效,因为我是Pandas的新手,我确信有一种更优雅的方式来做我想听到的。
谢谢,
答案 0 :(得分:1)
您可以编写一个函数,它接受三个参数today
,timeframe
和mindates
,并首先使用布尔索引将数据帧过滤到时间范围内的行。在此处,您可以按useridid
进行分组,并过滤掉不等于或超过mindates
的群组。
def find_dates(today, timeframe, mindates):
prev = today - np.timedelta64(timeframe-1, 'D')
df_new = df[df.date.between(prev, today)]
return df_new.groupby('usersidid').filter(lambda x: len(x) >= mindates).sort_values(['usersidid', 'date'])
today = pd.to_datetime('2017-01-05')
现在您可以使用您的特定参数调用您的函数。
find_dates(today, 5, 1)
usersidid date
5 1 2017-01-01
8 1 2017-01-04
1 1 2017-01-05
2 2 2017-01-02
6 2 2017-01-03
9 2 2017-01-05
7 3 2017-01-02
3 3 2017-01-04
4 4 2017-01-02
find_dates(today, 5, 2)
usersidid date
5 1 2017-01-01
8 1 2017-01-04
1 1 2017-01-05
2 2 2017-01-02
6 2 2017-01-03
9 2 2017-01-05
7 3 2017-01-02
3 3 2017-01-04
find_dates(today, 5, 3)
usersidid date
5 1 2017-01-01
8 1 2017-01-04
1 1 2017-01-05
2 2 2017-01-02
6 2 2017-01-03
9 2 2017-01-05
find_dates(today, 5, 4)
# returns empty dataframe
我不明白你的最后一个结果是如何使用timeframe = 3和mindates = 2的。 useridid 1和2在过去三天内都有两行。
find_dates(today, 3, 2)
usersidid date
8 1 2017-01-04
1 1 2017-01-05
6 2 2017-01-03
9 2 2017-01-05