第N高的薪水
题目来源:177. 第N高的薪水 - 力扣(LeetCode)
Employee表:
查询
Employee
表中第n
高的工资。如果没有第n
个最高工资,查询结果应该为null
。查询结果格式如下所示。
示例:
题解:
首先对薪水进行去重操作,使用drop_duplicates()
然后判断剩余的列长度是否大于等于N,如果不是的话就意味着不存在第N高的薪水
接下来对薪水进行降序排列,使用sort_values
并将ascending
设置为false,然后取出前N项,返回前N项的最后一项。
import pandas as pd
def nth_highest_salary(employee: pd.DataFrame, N: int) -> pd.DataFrame:
df = employee[["salary"]].drop_duplicates()
if(len(df) < N):
return pd.DataFrame({'getNthHighestSalary(2)': [None]})
return df.sort_values("salary", ascending=False).head(N).tail(1)
第二道题是获得第二高的薪水,大致思路和第N高的一致
import pandas as pd
def second_highest_salary(employee: pd.DataFrame) -> pd.DataFrame:
employee = employee.drop_duplicates(["salary"])
if len(employee["salary"].unique()) < 2:
return pd.DataFrame({"SecondHighestSalary" :[np.NaN]})
employee = employee.sort_values("salary", ascending=False)
employee.drop("id", axis = 1, inplace = True)
employee.rename({"salary": "SecondHighestSalary"}, axis = 1, inplace = True)
return employee.head(2).tail(1)
部门工资最高的员工
题目来源:184. 部门工资最高的员工 - 力扣(LeetCode)
Employee表:
Department表:
查找出每个部门中薪资最高的员工。
按 任意顺序 返回结果表。
查询结果格式如下例所示。示例:
题解:
参考:184. 部门工资最高的员工 - 力扣(LeetCode)
首先通过合并两个表来获得所有的部门名称、员工名称和薪水。
在合并后,原始表中具有相同名称的列(例如 name
)会被重命名(作为 name_x
和 name_y
),因此我们需要进行列重命名。
接下来,我们根据 Department 列对 df 进行分组,并对 Salary 列应用 transform(‘max’) 函数,这将为每个部门计算最高薪水,并返回一个与原 DataFrame 长度相同的 Series,其中每个值都是对应部门的最高薪水(它不一定是对应员工的薪水)。
0 90000
1 90000
2 80000
3 80000
4 90000
Name: Salary, dtype: int64
然后使用df[df['Salary'] == max_salary]
,可以选择所有薪水等于各自部门最高薪水的员工。
import pandas as pd
def department_highest_salary(employee: pd.DataFrame, department: pd.DataFrame) -> pd.DataFrame:
# 合并表以及重命名
df = employee.merge(department, left_on='departmentId', right_on='id', how='left')
df.rename(columns={'name_x': 'Employee', 'name_y': 'Department', 'salary': 'Salary'}, inplace=True)
# 选择工资等于部门最高工资的员工
max_salary = df.groupby('Department')['Salary'].transform('max')
df = df[df['Salary'] == max_salary]
return df[['Department', 'Employee', 'Salary']]
分数排名
题目:
Scores表:
查询并对分数进行排序。排名按以下规则计算:
- 分数应按从高到低排列。
- 如果两个分数相等,那么两个分数的排名应该相同。
- 在排名相同的分数后,排名数应该是下一个连续的整数。换句话说,排名之间不应该有空缺的数字。
按
score
降序返回结果表。查询结果格式如下所示。
示例:
题解:
理想情况下的做法是根据分数来对行进行分组,为每个组的成员分配相同的排名,但是传统的聚合函数使用依赖于将查询行分组到单个结果行中,但这道题是需要以所有行的排名方式来返回结果
例如对于示例输入,传统的聚合函数会给出以下的结果:
但是我们需要得到所有的行:
Pandas 提供了函数 rank()
来帮助计算沿轴的数值数据排名,我们可以将方法参数 method
设置为 dense
来分配密集排名。密集排名意味着当存在并列的值时,下一个排名不会跳过。相反,所有并列的分数都被分配相同的排名,并且下一个排名递增一。这确保排名没有间隙,并且每个分数获得唯一的排名,这也正是问题所需的。
import pandas as pd
def order_scores(scores: pd.DataFrame) -> pd.DataFrame:
scores['rank'] = scores['score'].rank(method='dense', ascending=False)
return scores[['score', 'rank']].sort_values('score', ascending=False)
删除重复的电子邮箱
题目来源:196. 删除重复的电子邮箱 - 力扣(LeetCode)
题目:
Person表:
删除 所有重复的电子邮件,只保留一个具有最小
id
的唯一电子邮件。(对于 SQL 用户,请注意你应该编写一个
DELETE
语句而不是SELECT
语句。)(对于 Pandas 用户,请注意你应该直接修改
Person
表。)运行脚本后,显示的答案是
Person
表。驱动程序将首先编译并运行您的代码片段,然后再显示Person
表。Person
表的最终顺序 无关紧要 。返回结果格式如下示例所示。
示例:
题解:
参考:196. 删除重复的电子邮箱 - 力扣(LeetCode)
要求是保留每个唯一电子邮件地址对应的最小 id
。自然地,我们可以考虑使用 groupby
方法来实现这一点。Person.groupby('email')
将根据 email
列中的唯一值对 Person
进行分组。我们根据email
列中的唯一值将Person
分成多个组。这种分组允许我们将具有相同email
的行分组在一起,以便我们可以分别对每个组进行操作。
我们想要找到每个组内的最小id
值,以保留具有最小id
的行。为了实现这一点,我们使用transform('min')
方法为每个组生成一个新的Series
,其中包含各自组内id
列中的最小值。
import pandas as pd
# Modify Person in place
def delete_duplicate_emails(person: pd.DataFrame) -> None:
min_id = person.groupby('email')['id'].transform('min')
removed_person = person[person['id'] != min_id]
person.drop(removed_person.index, inplace=True)
return
每个产品在不同商店的价格
题目来源:1795. 每个产品在不同商店的价格 - 力扣(LeetCode)
Products表:
请你重构
Products
表,查询每个产品在不同商店的价格,使得输出的格式变为(product_id, store, price)
。如果这一产品在商店里没有出售,则不输出这一行。输出结果表中的 顺序不作要求 。
查询输出格式请参考下面示例。
示例:
题解:
参考:1795. 每个产品在不同商店的价格 - 力扣(LeetCode)
Pandas中的melt()
方法可以将 DataFrame 从宽格式(wide format)转换为长格式(long format),并可以选择保留标识符。我们可以指定要堆叠的列及其对应的名称,从而更轻松地处理单个操作中的大量列。
id_vars
表示用作标识符变量的列,这里是 product_id
。value_vars
表示要进行堆叠的列。var_name='store'
表示包含 value_vars
的列将被命名为 store
。value_name='price'
表示’值’的列将被命名为 price
。
import pandas as pd
def rearrange_products_table(products: pd.DataFrame) -> pd.DataFrame:
df = products.melt(id_vars = 'product_id', value_vars = ['store1', 'store2', 'store3'], var_name = 'store', value_name = 'price')
df = df.dropna(axis=0)
return df