- 学习:知识的初次邂逅
- 复习:知识的温故知新
- 练习:知识的实践应用
目录
一,原题力扣链接
二,题干
支出表:
Spending
+-------------+---------+ | Column Name | Type | +-------------+---------+ | user_id | int | | spend_date | date | | platform | enum | | amount | int | +-------------+---------+ 这张表记录了用户在一个在线购物网站的支出历史,该在线购物平台同时拥有桌面端('desktop')和手机端('mobile')的应用程序。 (user_id, spend_date, platform) 是这张表的主键(具有唯一值的列的组合)。 平台列 platform 是一种 ENUM ,类型为('desktop', 'mobile')。编写解决方案找出每天 仅 使用手机端用户、仅 使用桌面端用户和 同时 使用桌面端和手机端的用户人数和总支出金额。
以 任意顺序 返回结果表。
返回结果格式如下例所示:
示例 1:
输入: Spending
table: +---------+------------+----------+--------+ | user_id | spend_date | platform | amount | +---------+------------+----------+--------+ | 1 | 2019-07-01 | mobile | 100 | | 1 | 2019-07-01 | desktop | 100 | | 2 | 2019-07-01 | mobile | 100 | | 2 | 2019-07-02 | mobile | 100 | | 3 | 2019-07-01 | desktop | 100 | | 3 | 2019-07-02 | desktop | 100 | +---------+------------+----------+--------+ 输出: +------------+----------+--------------+-------------+ | spend_date | platform | total_amount | total_users | +------------+----------+--------------+-------------+ | 2019-07-01 | desktop | 100 | 1 | | 2019-07-01 | mobile | 100 | 1 | | 2019-07-01 | both | 200 | 1 | | 2019-07-02 | desktop | 100 | 1 | | 2019-07-02 | mobile | 100 | 1 | | 2019-07-02 | both | 0 | 0 | +------------+----------+--------------+-------------+ 解释: 在 2019-07-01, 用户1 同时 使用桌面端和手机端购买, 用户2 仅 使用了手机端购买,而用户3 仅 使用了桌面端购买。 在 2019-07-02, 用户2 仅 使用了手机端购买, 用户3 仅 使用了桌面端购买,且没有用户 同时 使用桌面端和手机端购买。
三,建表语句
import pandas as pd
data = [[1, '2019-07-01', 'mobile', 100], [1, '2019-07-01', 'desktop', 100], [2, '2019-07-01', 'mobile', 100], [2, '2019-07-02', 'mobile', 100], [3, '2019-07-01', 'desktop', 100], [3, '2019-07-02', 'desktop', 100]]
spending = pd.DataFrame(data, columns=['user_id', 'spend_date', 'platform', 'amount']).astype({'user_id':'Int64', 'spend_date':'datetime64[ns]', 'platform':'object', 'amount':'Int64'})
四,分析
表格大法 创建维度表 和主表进行左连接
第一步:创建一个维度表;
第二步:转platform 为权重;
第三步:以日期,用户id分组 sum 聚合platform与金额列
第四步:把作为权重的platform转换回来
第五步:把维度表和我们第四步转换回来的表 左连接 连接条件双条件 日期与platfrom列
第六步:以日期和platfrom 分组 聚合 sum金额 与count用户id 统计人数
第七步:映射指定的列,改名,输出
解题过程
代码实现
第一步:创建一个维度表;
在pandas
第二步:转platform 为权重;
在pandas
第三步:以日期,用户id分组 sum 聚合platform与金额列
在pandas
第四步:把作为权重的platform转换回来
在pandas
第五步:把维度表和我们第四步转换回来的表 左连接 连接条件双条件 日期与platfrom列
在pandas
第六步:以日期和platfrom 分组 聚合 sum金额 与count用户id 统计人数
在pandas
第七步:映射指定的列,改名,输出
五,Pandas解答
import pandas as pd
def user_purchase(spending: pd.DataFrame) -> pd.DataFrame:
# 截取时间列 转为df对象,去重,重置索引
res=spending['spend_date'].to_frame().drop_duplicates().reset_index(drop=True)
#复制三个 df对象 然后创建一个临时表
df=res.copy()
df['pl'] ='mobile'
df1=res.copy()
df1['pl'] ='desktop'
df2=res.copy()
df2['pl'] ='both'
temp =pd.concat([df,df1,df2],axis=0)
# 转换平台为权重
spending['platform'] = spending['platform'].apply(lambda x: 1 if x=='mobile' else 2)
# 以日期,用户分组 聚合平台和金额
s = spending.groupby(['spend_date','user_id']).agg({'platform':'sum','amount':'sum'}).reset_index()
# 在把标签给转回来
def fun(x):
if x ==1:
return 'mobile'
elif x==2:
return 'desktop'
elif x==3:
return 'both'
s['platform'] = s['platform'].apply(fun)
# 左连接这2个表
s1 = pd.merge(temp,s,how='left',left_on=['pl','spend_date'],right_on=['platform','spend_date'])
# 求和金额 和聚合用户id
ress = s1.groupby(['spend_date','pl']).agg({'amount':'sum','user_id':'count'}).reset_index()
# 改名
ress = ress.rename(columns={'pl':'platform','amount':'total_amount','user_id':'total_users'})
return ress
user_purchase(spending)
六,验证
七,知识点总结
- Pandas抽取指定列的运用
- Pandas中转series对象为dataframe的运用 to_farme()
- Pandas中去重的运用 drop_duplicates
- Pandas中重置索引的运用 reset_index(drop=True)
- Pandas中复制的运用 copy
- Pandas中实现sql中union的效果的运用 concat。。。axis=0
- Pandas中对某列转换的运用
- Pnadas中自定义函数的运用 apply
- Python中三目运算符的运用
- Python中匿名函数的运用
- Pandas中多列分组的运用 groupby
- Pandas中多列聚合的运用 egg
- Pandas中实现sql中case whent then语法的运用
- Pandas中左连接的运用 merge
- Pandas中左连接 连接的条件是多列运用
- Pandas中多列分组+多列聚合的运用
- Pandas中改名的运用
- Pyhton中函数的运用
- 学习:知识的初次邂逅
- 复习:知识的温故知新
- 练习:知识的实践应用