- 学习:知识的初次邂逅
- 复习:知识的温故知新
- 练习:知识的实践应用
目录
一,原题力扣链接
二,题干
Traffic
表:+---------------+---------+ | Column Name | Type | +---------------+---------+ | user_id | int | | activity | enum | | activity_date | date | +---------------+---------+ 该表可能有重复的行。 activity 列是 ENUM 类型,可能取 ('login', 'logout', 'jobs', 'groups', 'homepage') 几个值之一。编写解决方案,找出从今天起最多 90 天内,每个日期该日期首次登录的用户数。假设今天是 2019-06-30 。
以 任意顺序 返回结果表。
结果格式如下所示。
示例 1:
输入: Traffic 表: +---------+----------+---------------+ | user_id | activity | activity_date | +---------+----------+---------------+ | 1 | login | 2019-05-01 | | 1 | homepage | 2019-05-01 | | 1 | logout | 2019-05-01 | | 2 | login | 2019-06-21 | | 2 | logout | 2019-06-21 | | 3 | login | 2019-01-01 | | 3 | jobs | 2019-01-01 | | 3 | logout | 2019-01-01 | | 4 | login | 2019-06-21 | | 4 | groups | 2019-06-21 | | 4 | logout | 2019-06-21 | | 5 | login | 2019-03-01 | | 5 | logout | 2019-03-01 | | 5 | login | 2019-06-21 | | 5 | logout | 2019-06-21 | +---------+----------+---------------+ 输出: +------------+-------------+ | login_date | user_count | +------------+-------------+ | 2019-05-01 | 1 | | 2019-06-21 | 2 | +------------+-------------+ 解释: 请注意,我们只关心用户数非零的日期. ID 为 5 的用户第一次登陆于 2019-03-01,因此他不算在 2019-06-21 的的统计内。
三,建表语句
import pandas as pd
data = [[1, 'login', '2019-05-01'], [1, 'homepage', '2019-05-01'], [1, 'logout', '2019-05-01'], [2, 'login', '2019-06-21'], [2, 'logout', '2019-06-21'], [3, 'login', '2019-01-01'], [3, 'jobs', '2019-01-01'], [3, 'logout', '2019-01-01'], [4, 'login', '2019-06-21'], [4, 'groups', '2019-06-21'], [4, 'logout', '2019-06-21'], [5, 'login', '2019-03-01'], [5, 'logout', '2019-03-01'], [5, 'login', '2019-06-21'], [5, 'logout', '2019-06-21']]
traffic = pd.DataFrame(data, columns=['user_id', 'activity', 'activity_date']).astype({'user_id':'Int64', 'activity':'object', 'activity_date':'datetime64[ns]'})
四,分析
表格大法:过滤+分组过滤
第一步:过滤掉非login的行数
第二步:计算每个用户首次登录的日期;
第三步:过滤掉首次登录的日期不是在 2019-06-30 前90天的行数
第四步:以日期分组 聚合用户id (去重一下 有可能某用户当天重复多次登录~)
第五步:改名并输出
思路
表格大法:过滤+分组过滤 第一步:过滤掉非login的行数 第二步:计算每个用户首次登录的日期; 第三步:过滤掉首次登录的日期不是在 2019-06-30 前90天的行数 第四步:以日期分组 聚合用户id (去重一下 有可能某用户当天重复多次登录~) 第五步:改名并输出
逻辑见表格:
解题过程
第一步:过滤掉非login的行数
在pandas中
第二步:计算每个用户首次登录的日期;
在pandas中
第三步:过滤掉首次登录的日期不是在 2019-06-30 前90天的行数
在pandas中
第四步:以日期分组 聚合用户id (去重一下 有可能某用户当天重复多次登录~)
在pandas中
第五步:改名并输出
五,Pandas解答
import pandas as pd
def new_users_daily_count(traffic: pd.DataFrame) -> pd.DataFrame:
#只关注login的行数
traffic = traffic[traffic['activity']=='login'].reset_index()
#拿到首次登录的日期
traffic['min_date'] = traffic.groupby('user_id')['activity_date'].transform('min')
res1 = traffic[traffic['min_date']<='2019-06-30'] #小于等于今天 2019-06-30
res2 = res1[res1['min_date']>= (pd.to_datetime('2019-06-30') -pd.offsets.DateOffset(90))] #大于等于90天之前
df = res2[['user_id','activity','min_date']]
df = df.drop_duplicates()
df1 = df.groupby('min_date')['user_id'].count().reset_index()
df2 = df1.rename(columns={'min_date':'login_date','user_id':'user_count'})
return df2
new_users_daily_count(traffic)
六,验证
七,知识点总结
- Pandas中 过滤的运用
- Pandas中 重置索引的运用
- Pandas中 min实现开窗函数的效果的运用 transform
- Pandas中 时间函数的运用 转为时间类型 pd.to_datetime
- Pandas中 时间差的运用 pd.offsets.DateOffset 天
- Pandas中去重的运用 drop_dupliates
- Pandas中 分组聚合的运用
- Pandas中 改名的运用
- 学习:知识的初次邂逅
- 复习:知识的温故知新
- 练习:知识的实践应用