本文围绕力扣的Pandas简单题集,解析如何用Pandas完成基础数据处理任务,适合Pandas初学者学习。
题目1:1741. 查找每个员工花费的总时间
题目描述:
表: Employees
+-------------+------+
| Column Name | Type |
+-------------+------+
| emp_id | int |
| event_day | date |
| in_time | int |
| out_time | int |
+-------------+------+
在 SQL 中,(emp_id, event_day, in_time) 是这个表的主键。
该表显示了员工在办公室的出入情况。
event_day 是此事件发生的日期,in_time 是员工进入办公室的时间,而 out_time 是他们离开办公室的时间。
in_time 和 out_time 的取值在1到1440之间。
题目保证同一天没有两个事件在时间上是相交的,并且保证 in_time 小于 out_time。
计算每位员工每天在办公室花费的总时间(以分钟为单位)。 请注意,在一天之内,同一员工是可以多次进入和离开办公室的。 在办公室里一次进出所花费的时间为out_time 减去 in_time。
返回结果表单的顺序无要求。
解题思路:
使用groupby()方法按event_day和emp_id进行分组,再将分组内的out_time减去in_time进行求和。
题目代码:
import pandas as pd
def total_time(employees: pd.DataFrame) -> pd.DataFrame:
#总共的时间等于出去的时间减去进来的时间
employees["total_time"] = employees["out_time"] - employees["in_time"]
#按event_day和emp_id两个列进行分组,对每个分组中的total_time进行求和,重置索引
employees = employees.groupby(["event_day", "emp_id"])["total_time"].sum().reset_index()
#修改列名
employees.rename({"event_day": "day"}, axis=1, inplace=True)
#将day数据类型转换为字符串类型
employees["day"] = employees["day"].astype(str)
return employees
题目2:511. 游戏玩法分析 I
题目描述:
活动表 Activity:
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| player_id | int |
| device_id | int |
| event_date | date |
| games_played | int |
+--------------+---------+
在 SQL 中,表的主键是 (player_id, event_date)。这张表展示了一些游戏玩家在游戏平台上的行为活动。每行数据记录了一名玩家在退出平台之前,当天使用同一台设备登录平台后打开的游戏的数目(可能是 0 个)。
查询每位玩家 第一次登录平台的日期。
查询结果的格式如下所示:
Activity 表:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1 | 2 | 2016-03-01 | 5 |
| 1 | 2 | 2016-05-02 | 6 |
| 2 | 3 | 2017-06-25 | 1 |
| 3 | 1 | 2016-03-02 | 0 |
| 3 | 4 | 2018-07-03 | 5 |
+-----------+-----------+------------+--------------+
Result 表:
+-----------+-------------+
| player_id | first_login |
+-----------+-------------+
| 1 | 2016-03-01 |
| 2 | 2017-06-25 |
| 3 | 2016-03-02 |
+-----------+-------------+
解题思路:
按player_id分组,找出nvent_date中最小的日期。
题目代码:
import pandas as pd
def game_analysis(activity: pd.DataFrame) -> pd.DataFrame:
df = activity.groupby('player_id')['event_date'].min().reset_index()
return df.rename(columns = {'event_date':'first_login'})
题目3:2356. 每位教师所教授的科目种类的数量
题目描述:
表: Teacher
+-------------+------+
| Column Name | Type |
+-------------+------+
| teacher_id | int |
| subject_id | int |
| dept_id | int |
+-------------+------+
在 SQL 中,(subject_id, dept_id) 是该表的主键。
该表中的每一行都表示带有 teacher_id 的教师在系 dept_id 中教授科目 subject_id。
查询每位老师在大学里教授的科目种类的数量。
以 任意顺序 返回结果表。
解题思路:
使用groupby()方法按teacher_id分组并使用nuique()计算每组不同的subject_id数量。
题目代码:
import pandas as pd
def count_unique_subjects(teacher: pd.DataFrame) -> pd.DataFrame:
#按teacher_id分组并计算每组不同的subject_id数量
result = teacher.groupby('teacher_id')['subject_id'].nunique().reset_index()
result.columns = ['teacher_id', 'cnt']
return result
题目4:596. 超过 5 名学生的课
题目描述:
表: Courses
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| student | varchar |
| class | varchar |
+-------------+---------+
(student, class)是该表的主键(不同值的列的组合)。
该表的每一行表示学生的名字和他们注册的班级。
查询 至少有 5 个学生 的所有班级。
以 任意顺序 返回结果表。
解题思路:
按班级分开,计算每个班级对应学生的数量,筛选出有五个以上的班级,将班级列作为返回值返回。
题目代码:
import pandas as pd
def find_classes(courses: pd.DataFrame) -> pd.DataFrame:
#按class分开并计算class对应的不同student的数量,重置索引并筛选条件
result = courses.groupby('class')['student'].nunique().reset_index().query('student>=5')
result=result.rename(columns={'student': 'student_count'})
return result[['class']]
题目5:586. 订单最多的客户
题目描述:
表: Orders
+-----------------+----------+
| Column Name | Type |
+-----------------+----------+
| order_number | int |
| customer_number | int |
+-----------------+----------+
在 SQL 中,Order_number是该表的主键。
此表包含关于订单ID和客户ID的信息。
查找下了 最多订单 的客户的 customer_number 。
测试用例生成后, 恰好有一个客户 比任何其他客户下了更多的订单。
查询结果格式如下所示。
示例 1:
输入:
Orders 表:
+--------------+-----------------+
| order_number | customer_number |
+--------------+-----------------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 3 |
+--------------+-----------------+
输出:
+-----------------+
| customer_number |
+-----------------+
| 3 |
+-----------------+
解释:
customer_number 为 '3' 的顾客有两个订单,比顾客 '1' 或者 '2' 都要多,因为他们只有一个订单。
所以结果是该顾客的 customer_number ,也就是 3 。
解题思路:
方法1:计算每个客户的订单数量,再按数量降序排列,题目确定有且仅有一个最多的客户,以第一行数据作为返回值返回。提交时空值报错,还需要判断数据是否为空。
方法2:计算每个客户的订单数量,找到最大的一行作为返回值返回。与方法1相比,由于没有使用排序以及指定第一行数据,所以不需判断数据是否为空。
题目代码:
方法1:
import pandas as pd
def largest_orders(orders: pd.DataFrame) -> pd.DataFrame:
# 计算每个客户的订单数量
customer_counts = orders['customer_number'].value_counts().reset_index()
customer_counts.columns = ['customer_number', 'order_count']
#判断是否有数据
if not customer_counts.empty:
#降序
customer_counts = customer_counts.sort_values('order_count', ascending=False)
#题目保证有且只有一个。降序之后获取第一个
result = customer_counts.head(1)[['customer_number']]
return result
else:
return pd.DataFrame(columns=['customer_number'])
方法2:
import pandas as pd
def largest_orders(orders: pd.DataFrame) -> pd.DataFrame:
#计算每个客户的订单数量
df = orders.groupby('customer_number')['order_number'].count().reset_index()
# 找到最大值的一行
df = df[df['order_number'] == df['order_number'].max()]
return df[['customer_number']]
题目6:1484. 按日期分组销售产品
题目描述:
表 Activities:
+-------------+---------+
| 列名 | 类型 |
+-------------+---------+
| sell_date | date |
| product | varchar |
+-------------+---------+
该表没有主键(具有唯一值的列)。它可能包含重复项。
此表的每一行都包含产品名称和在市场上销售的日期。
编写解决方案找出每个日期、销售的不同产品的数量及其名称。
每个日期的销售产品名称应按词典序排列。
返回按 sell_date 排序的结果表。
解题思路:
分组计算num_sold和products,最后合并为dataframe数据返回。
题目代码:
import pandas as pd
def categorize_products(activities: pd.DataFrame) -> pd.DataFrame:
#分组,计算每组不同产品数量
grouped = activities.groupby('sell_date')['product']
num_sold = grouped.nunique()
#去重、排序、连接
products = grouped.apply(lambda x: ','.join(sorted(x.unique())))
# 合并结果
result = pd.DataFrame({
'num_sold': num_sold,
'products': products
}).reset_index().sort_values('sell_date')
return result
题目7:1693. 每天的领导和合伙人
题目描述:
表:DailySales
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| date_id | date |
| make_name | varchar |
| lead_id | int |
| partner_id | int |
+-------------+---------+
该表没有主键(具有唯一值的列)。它可能包含重复项。
该表包含日期、产品的名称,以及售给的领导和合伙人的编号。
名称只包含小写英文字母。
对于每一个 date_id 和 make_name,找出 不同 的 lead_id 以及 不同 的 partner_id 的数量。
按 任意顺序 返回结果表。
解题思路:
使用groupby()方法对date_id和make_name进行分组,在计算每个组内lead_id和partner_id中不同数据数量,并使用agg()方法聚合,重命名之后返回dataframe数据作为返回值。
题目代码:
import pandas as pd
def daily_leads_and_partners(daily_sales: pd.DataFrame) -> pd.DataFrame:
#使用groupby()分组,分别计算lead_id和partner_id中不同数据数量并使用agg聚合
df = daily_sales.groupby(['date_id', 'make_name']).agg({
'lead_id': 'nunique',
'partner_id': 'nunique'
}).reset_index()
df = df.rename(columns={
'lead_id': 'unique_leads',
'partner_id': 'unique_partners'
})
return df