力扣 Pandas 挑战(6)---数据合并
本文围绕力扣的Pandas简单题集,解析如何用Pandas完成基础数据处理任务,适合Pandas初学者学习。
题目1:1050. 合作过至少三次的演员和导演
题目描述:
ActorDirector 表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| actor_id | int |
| director_id | int |
| timestamp | int |
+-------------+---------+
timestamp 是这张表的主键(具有唯一值的列).
编写解决方案找出合作过至少三次的演员和导演的 id 对 (actor_id, director_id)
示例 1:
输入:
ActorDirector 表:
+-------------+-------------+-------------+
| actor_id | director_id | timestamp |
+-------------+-------------+-------------+
| 1 | 1 | 0 |
| 1 | 1 | 1 |
| 1 | 1 | 2 |
| 1 | 2 | 3 |
| 1 | 2 | 4 |
| 2 | 1 | 5 |
| 2 | 1 | 6 |
+-------------+-------------+-------------+
输出:
+-------------+-------------+
| actor_id | director_id |
+-------------+-------------+
| 1 | 1 |
+-------------+-------------+
解释:
唯一的 id 对是 (1, 1),他们恰好合作了 3 次。
解题思路:
方法1:使用 value_counts() 直接统计每对的出现次数。
方法2:按actor_id和director_id分为两组,使用size()计算每组行数,筛选出大于等于3的数据。
题目代码:
方法1:
import pandas as pd
def actors_and_directors(actor_director: pd.DataFrame) -> pd.DataFrame:# 使用value_counts()直接统计counts = actor_director[['actor_id', 'director_id']].value_counts()# 筛选并重置索引result = counts[counts >= 3].reset_index()[['actor_id', 'director_id']]return result
方法2:
import pandas as pd
def actors_and_directors(actor_director: pd.DataFrame) -> pd.DataFrame:# 统计每对演员和导演的合作次数collaboration_counts = actor_director.groupby(['actor_id', 'director_id']).size().reset_index(name='count')# 筛选次数≥3的result = collaboration_counts[collaboration_counts['count'] >= 3]return result[['actor_id', 'director_id']]
题目2:1378. 使用唯一标识码替换员工ID
题目描述:
Employees 表:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
在 SQL 中,id 是这张表的主键。
这张表的每一行分别代表了某公司其中一位员工的名字和 ID 。
EmployeeUNI 表:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| unique_id | int |
+---------------+---------+
在 SQL 中,(id, unique_id) 是这张表的主键。
这张表的每一行包含了该公司某位员工的 ID 和他的唯一标识码(unique ID)。
展示每位用户的 唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。
你可以以 任意 顺序返回结果表。
解题思路:
使用merge()方法根据id将数据合并,如果没有对应的数据,则填充为NaN。
题目代码:
import pandas as pddef replace_employee_id(employees: pd.DataFrame, employee_uni: pd.DataFrame) -> pd.DataFrame:#根据id将数据合并,无对应数据则填充为NaNemployee_name_uni = pd.merge(employees, employee_uni, on='id', how='left')return employee_name_uni[['unique_id', 'name']]
题目3:1280. 学生们参加各科测试的次数
题目描述:
学生表: Students
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| student_id | int |
| student_name | varchar |
+---------------+---------+
在 SQL 中,主键为 student_id(学生ID)。
该表内的每一行都记录有学校一名学生的信息。
科目表: Subjects
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| subject_name | varchar |
+--------------+---------+
在 SQL 中,主键为 subject_name(科目名称)。
每一行记录学校的一门科目名称。
考试表: Examinations
+--------------+---------+
| Column Name | Type |
+--------------+---------+
| student_id | int |
| subject_name | varchar |
+--------------+---------+
这个表可能包含重复数据(换句话说,在 SQL 中,这个表没有主键)。
学生表里的一个学生修读科目表里的每一门科目。
这张考试表的每一行记录就表示学生表里的某个学生参加了一次科目表里某门科目的测试。
查询出每个学生参加每一门科目测试的次数,结果按 student_id 和 subject_name 排序。
解题思路:
该题目包含多种对dataframe数据的操作,分解为多个问题来解答。
首先按id和科目分组,并计算考试次数,合并dataframe数据,填充缺失值,最后按照升序排序。
题目代码:
import pandas as pddef students_and_examinations(students: pd.DataFrame, subjects: pd.DataFrame,examinations: pd.DataFrame) -> pd.DataFrame:#按id和科目分组,并计算考试次数。grouped = examinations.groupby(['student_id', 'subject_name']).size().reset_index(name='attended_exams')# 获取id和subject的所有组合all_id_subjects = pd.merge(students, subjects, how='cross')# 左连接id_subjects_count = pd.merge(all_id_subjects, grouped, on=['student_id', 'subject_name'], how='left')#缺失值填充id_subjects_count['attended_exams'] = id_subjects_count['attended_exams'].fillna(0).astype(int)#升序排序id_subjects_count.sort_values(['student_id', 'subject_name'], inplace=True)return id_subjects_count[['student_id', 'student_name', 'subject_name', 'attended_exams']]
题目4:570. 至少有5名直接下属的经理
题目描述:
表: Employee
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| name | varchar |
| department | varchar |
| managerId | int |
+-------------+---------+
id 是此表的主键(具有唯一值的列)。
该表的每一行表示雇员的名字、他们的部门和他们的经理的id。
如果managerId为空,则该员工没有经理。
没有员工会成为自己的管理者。
编写一个解决方案,找出至少有五个直接下属的经理。
以 任意顺序 返回结果表。
解题思路:
使用groupby()方法按managerid分组,计算每组id数量,即经理的下属数量,然后筛选出数量大于等于5个的数据id,再找到数据id对应的name数据。
题目代码:
import pandas as pd
def find_managers(employee: pd.DataFrame) -> pd.DataFrame:#按managerId分组,计算每组id数量,即下属数量subordinate_count = employee.groupby('managerId')['id'].count()#筛选出下属数量大于等于5的数据managers_with_5_subordinates = subordinate_count[subordinate_count >= 5].index#找出筛选出的id所对应的姓名name数据result = employee[employee['id'].isin(managers_with_5_subordinates)]['name']return result.to_frame(name='name')
题目5:607. 销售员
题目描述:
表: SalesPerson
+-----------------+---------+
| Column Name | Type |
+-----------------+---------+
| sales_id | int |
| name | varchar |
| salary | int |
| commission_rate | int |
| hire_date | date |
+-----------------+---------+
sales_id 是该表的主键列(具有唯一值的列)。
该表的每一行都显示了销售人员的姓名和 ID ,以及他们的工资、佣金率和雇佣日期。
表: Company
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| com_id | int |
| name | varchar |
| city | varchar |
+-------------+---------+
com_id 是该表的主键列(具有唯一值的列)。
该表的每一行都表示公司的名称和 ID ,以及公司所在的城市。
表: Orders
+-------------+------+
| Column Name | Type |
+-------------+------+
| order_id | int |
| order_date | date |
| com_id | int |
| sales_id | int |
| amount | int |
+-------------+------+
order_id 是该表的主键列(具有唯一值的列)。
com_id 是 Company 表中 com_id 的外键(reference 列)。
sales_id 是来自销售员表 sales_id 的外键(reference 列)。
该表的每一行包含一个订单的信息。这包括公司的 ID 、销售人员的 ID 、订单日期和支付的金额。
编写解决方案,找出没有任何与名为 “RED” 的公司相关的订单的所有销售人员的姓名。
以 任意顺序 返回结果表。
解题思路:
找到与red有关的订单,根据订单找相关的销售人员,找出不在这些销售人员名单中的其他销售人员。
题目代码:
import pandas as pddef sales_person(sales_person: pd.DataFrame, company: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:#筛选与red有关的订单red_company = company[company['name'] == 'RED']if red_company.empty:return sales_person[['name']]red_orders = orders[orders['com_id'] == red_company['com_id'].iloc[0]]# 找出这些订单对应的销售人员IDred_sales_ids = red_orders['sales_id'].unique()# 找出不在这些销售人员名单中的所有销售人员non_red_sales = sales_person[~sales_person['sales_id'].isin(red_sales_ids)]return non_red_sales[['name']]