该题目来源于力扣pandas题库,链接如下:
1327. 列出指定时间段内所有的下单产品 - 力扣(LeetCode)
——题目需求:
表: Products
+------------------+---------+ | Column Name | Type | +------------------+---------+ | product_id | int | | product_name | varchar | | product_category | varchar | +------------------+---------+ product_id 是该表主键(具有唯一值的列)。 该表包含该公司产品的数据。
表: Orders
+---------------+---------+ | Column Name | Type | +---------------+---------+ | product_id | int | | order_date | date | | unit | int | +---------------+---------+ 该表可能包含重复行。 product_id 是表单 Products 的外键(reference 列)。 unit 是在日期 order_date 内下单产品的数目。
写一个解决方案,要求获取在 2020 年 2 月份下单的数量不少于 100 的产品的名字和数目。
返回结果表单的 顺序无要求 。
查询结果的格式如下。
示例 1:
输入: Products 表: +-------------+-----------------------+------------------+ | product_id | product_name | product_category | +-------------+-----------------------+------------------+ | 1 | Leetcode Solutions | Book | | 2 | Jewels of Stringology | Book | | 3 | HP | Laptop | | 4 | Lenovo | Laptop | | 5 | Leetcode Kit | T-shirt | +-------------+-----------------------+------------------+ Orders 表: +--------------+--------------+----------+ | product_id | order_date | unit | +--------------+--------------+----------+ | 1 | 2020-02-05 | 60 | | 1 | 2020-02-10 | 70 | | 2 | 2020-01-18 | 30 | | 2 | 2020-02-11 | 80 | | 3 | 2020-02-17 | 2 | | 3 | 2020-02-24 | 3 | | 4 | 2020-03-01 | 20 | | 4 | 2020-03-04 | 30 | | 4 | 2020-03-04 | 60 | | 5 | 2020-02-25 | 50 | | 5 | 2020-02-27 | 50 | | 5 | 2020-03-01 | 50 | +--------------+--------------+----------+ 输出: +--------------------+---------+ | product_name | unit | +--------------------+---------+ | Leetcode Solutions | 130 | | Leetcode Kit | 100 | +--------------------+---------+ 解释: 2020 年 2 月份下单 product_id = 1 的产品的数目总和为 (60 + 70) = 130 。 2020 年 2 月份下单 product_id = 2 的产品的数目总和为 80 。 2020 年 2 月份下单 product_id = 3 的产品的数目总和为 (2 + 3) = 5 。 2020 年 2 月份 product_id = 4 的产品并没有下单。 2020 年 2 月份下单 product_id = 5 的产品的数目总和为 (50 + 50) = 100 。
——思路解释
首先将
两表格进行按product_id列进行合并,然后将时间列中的数据转化为时间类型形式,实现数据清洗,利用groupby函数找出符合题目要求的时间段;然后通过分组函数和聚合函数求解每个用户的所有下单数量,再次用query函数找到不小于100的数据即可。
——代码实现
import pandas as pd
def list_products(products: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
data = pd.merge(products, orders, on='product_id')
data['order_date'] = pd.to_datetime(data['order_date']) # 将整个列转换为datetime
data=data.query("order_date >= '2020-02-01' & order_date <='2020-02-29'")
#注意,groupby函数和聚合函数返回的数据只包括groupby函数和聚合函数内部的列
a = data.groupby('product_id').agg({'unit':'sum'}).reset_index() #必须要重置索引
#进行第二次合并进行求解
result= pd.merge(products,a,how='left',on='product_id')
result=result.query("unit >= 100")
return result[['product_name','unit']]
——细节思考
注意,如果把一个数据框按照列A进行分组,并在后续添加了一个关于列B的聚合函数,那么生成的数据只包括列A和列B
import pandas as pd
def list_products(products: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
data = pd.merge(products, orders, on='product_id')
data['order_date'] = pd.to_datetime(data['order_date']) # 将整个列转换为datetime
#细节处理!!!
data=data.query("order_date >= '2020-02-01' & order_date <='2020-02-29'")
a = data.groupby('product_id').agg({'unit':'sum'}).reset_index() #必须要重置索引
return a
'''
| product_id | unit |
| ---------- | ---- |
| 1 | 130 |
| 2 | 80 |
| 3 | 5 |
| 5 | 100 |
'''
可见,以上代码只生成了product_id和unit列的数据框。
因此,如果想彻底解决题目需求,只需要将分组聚合后的数据框于源数据进行再次合并并且查询即可。