题解 | #牛客网连续练习题目3天及以上的用户#
首先梳理一下本题型的核心解题思路:求计算连续N天及以上的XXX
我这里举个例子:请用目测法告诉我,以下最长连续签到时间是几天?
2022-08-01 2022-08-02 2022-08-03 2022-08-05 2022-08-06 2022-08-07 2022-08-08 2022-08-09 2022-08-10 2022-08-13 2022-08-14 2022-08-15 2022-08-16
答案是6天,签到日期为2022-08-05到2022-08-10
那么我们可以如何计算?题目要求是连续登录,重点是连续,那么一串连续的数字里有什么是保持不变的?那就是公差。
连续日期的单元单位是1,所以我们可以作出公差为1的等差数列作为辅助,如下所示
2022-08-01 1 2022-08-02 2 2022-08-03 3 2022-08-05 4 2022-08-06 5 2022-08-07 6 2022-08-08 7 2022-08-09 8 2022-08-10 9 2022-08-13 10 2022-08-14 11 2022-08-15 12 2022-08-16 13这一步依然没看懂?再来看看下一步,将两列作差,请看看得到的结果
2022-08-01 1 2022-07-31 2022-08-02 2 2022-07-31 2022-08-03 3 2022-07-31 2022-08-05 4 2022-08-01 2022-08-06 5 2022-08-01 2022-08-07 6 2022-08-01 2022-08-08 7 2022-08-01 2022-08-09 8 2022-08-01 2022-08-10 9 2022-08-01 2022-08-13 10 2022-08-03 2022-08-14 11 2022-08-03 2022-08-15 12 2022-08-03 2022-08-16 13 2022-08-03第三列其实就是我们想要知道的结果,每个字符出现的次数就是连续的次数!
譬如'2022-07-31'出现3次,代表连续签到3天
'2022-08-01'出现6次,代表连续签到6天
'2022-08-03'出现4次,代表连续签到4天
所以最长连续签到是6天。
所以最长连续签到是6天。
掌握了以上思路,那么直接看本题的解答(图文并茂)
首先准备模拟数据:nowcoder.csv
user_id,question_id,result,date 3270,110,wrong,2021/12/1 8:28 3328,111,wrong,2021/12/1 10:09 3617,121,right,2021/12/2 12:12 3344,112,right,2021/12/1 12:31 3415,113,wrong,2021/12/1 12:34 3712,119,right,2021/12/1 15:21 3516,114,right,2021/12/1 13:15 3518,115,right,2021/12/1 12:23 3516,116,right,2021/12/2 9:34 3712,123,right,2021/12/2 10:52 3516,117,wrong,2021/12/3 14:33 3617,118,right,2021/12/1 18:31 3617,122,wrong,2021/12/3 14:52 3712,125,wrong,2021/12/3 13:32 3328,129,wrong,2021/12/2 13:09 3270,130,right,2021/12/4 15:32 3270,131,wrong,2021/12/5 15:32最开始先导包、取数
import pandas as pd df = pd.read_csv('nowcoder.csv')
第一步:日期格式化成 yyyy-mm-dd
df.date = pd.to_datetime(df.date,format="%Y-%m-%d").dt.date
第二步:构建辅助有序自增列
df['order'] = df.groupby('user_id')['date'].rank(method="dense")
第三步:按照user_id、date排序
df.sort_values(by=['user_id','date'],ascending=True,inplace=True)
第四步:用date和第二步的辅助列作差
df['date_sub'] = pd.to_datetime(df.date)- pd.to_timedelta(df.order,unit='d')
第五步:按照user_id、date_sub来分组,用count()聚合即可得知该user_id最长连续登录天数
df = df.groupby(['user_id','date_sub']).count().reset_index()
第六步:按照题目要求输出
print(df.query("date >= 3").groupby('user_id')['date'].sum())
完整代码如下:
import pandas as pd df = pd.read_csv('nowcoder.csv') # 第一步:日期格式化成 yyyy-mm-dd df.date = pd.to_datetime(df.date,format="%Y-%m-%d").dt.date # 第二步:构建辅助有序自增列 df['order'] = df.groupby('user_id')['date'].rank(method="dense") # 第三步:按照user_id、date排序 df.sort_values(by=['user_id','date'],ascending=True,inplace=True) # 第四步:用date和第二步的辅助列作差 df['date_sub'] = pd.to_datetime(df.date)- pd.to_timedelta(df.order,unit='d') # 第五步:按照user_id、date_sub来分组,用count()聚合即可得知该user_id最长连续登录天数 df = df.groupby(['user_id','date_sub']).count().reset_index() # 第六步:按照题目要求输出 print(df.query("date >= 3").groupby('user_id')['date'].sum())