From c04979f01eaadbd4daa0bbad1b8ebd6b0d1aeac2 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 10 Jun 2025 06:37:55 +0800 Subject: [PATCH] feat: update solution to lc problem: No.3580 No.3580.Find Consistently Improving Employees --- .../README.md | 82 ++++++++----------- .../README_EN.md | 82 ++++++++----------- .../Solution.py | 60 +++++++------- .../Solution.sql | 22 ++--- 4 files changed, 108 insertions(+), 138 deletions(-) diff --git a/solution/3500-3599/3580.Find Consistently Improving Employees/README.md b/solution/3500-3599/3580.Find Consistently Improving Employees/README.md index fb4c1847d130a..5f12b8383cebb 100644 --- a/solution/3500-3599/3580.Find Consistently Improving Employees/README.md +++ b/solution/3500-3599/3580.Find Consistently Improving Employees/README.md @@ -174,33 +174,27 @@ WITH recent AS ( SELECT employee_id, - rating, review_date, ROW_NUMBER() OVER ( PARTITION BY employee_id ORDER BY review_date DESC ) AS rn, - LAG(rating) OVER ( - PARTITION BY employee_id - ORDER BY review_date DESC - ) AS prev_rating + ( + LAG(rating) OVER ( + PARTITION BY employee_id + ORDER BY review_date DESC + ) - rating + ) AS delta FROM performance_reviews - ), - deltas AS ( - SELECT - employee_id, - prev_rating - rating AS delta, - rn - FROM recent - WHERE rn > 1 AND rn <= 3 ) SELECT employee_id, name, SUM(delta) AS improvement_score FROM - deltas + recent JOIN employees USING (employee_id) +WHERE rn > 1 AND rn <= 3 GROUP BY 1 HAVING COUNT(*) = 2 AND MIN(delta) > 0 ORDER BY 3 DESC, 2; @@ -215,42 +209,38 @@ import pandas as pd def find_consistently_improving_employees( employees: pd.DataFrame, performance_reviews: pd.DataFrame ) -> pd.DataFrame: - recent = ( - performance_reviews.sort_values( - ["employee_id", "review_date"], ascending=[True, False] - ) - .groupby("employee_id") - .head(3) + performance_reviews = performance_reviews.sort_values( + ["employee_id", "review_date"], ascending=[True, False] ) - - three_reviews_ids = recent["employee_id"].value_counts().loc[lambda s: s == 3].index - recent = recent[recent["employee_id"].isin(three_reviews_ids)] - recent = recent.sort_values(["employee_id", "review_date"]) - - def strictly_increasing(ratings: pd.Series) -> bool: - return (ratings.diff().dropna() > 0).all() - - improving_ids = ( - recent.groupby("employee_id")["rating"] - .apply(strictly_increasing) - .loc[lambda s: s] - .index + performance_reviews["rn"] = ( + performance_reviews.groupby("employee_id").cumcount() + 1 ) - improving = recent[recent["employee_id"].isin(improving_ids)] - - scores = ( - improving.groupby("employee_id")["rating"] - .agg(lambda x: x.iloc[-1] - x.iloc[0]) - .reset_index(name="improvement_score") + performance_reviews["lag_rating"] = performance_reviews.groupby("employee_id")[ + "rating" + ].shift(1) + performance_reviews["delta"] = ( + performance_reviews["lag_rating"] - performance_reviews["rating"] ) - - result = ( - scores.merge(employees, on="employee_id") - .loc[:, ["employee_id", "name", "improvement_score"]] - .sort_values(["improvement_score", "name"], ascending=[False, True]) - .reset_index(drop=True) + recent = performance_reviews[ + (performance_reviews["rn"] > 1) & (performance_reviews["rn"] <= 3) + ] + improvement = ( + recent.groupby("employee_id") + .agg( + improvement_score=("delta", "sum"), + count=("delta", "count"), + min_delta=("delta", "min"), + ) + .reset_index() + ) + improvement = improvement[ + (improvement["count"] == 2) & (improvement["min_delta"] > 0) + ] + result = improvement.merge(employees[["employee_id", "name"]], on="employee_id") + result = result.sort_values( + by=["improvement_score", "name"], ascending=[False, True] ) - return result + return result[["employee_id", "name", "improvement_score"]] ``` diff --git a/solution/3500-3599/3580.Find Consistently Improving Employees/README_EN.md b/solution/3500-3599/3580.Find Consistently Improving Employees/README_EN.md index 32b5c24165871..c9d0cff2f5e28 100644 --- a/solution/3500-3599/3580.Find Consistently Improving Employees/README_EN.md +++ b/solution/3500-3599/3580.Find Consistently Improving Employees/README_EN.md @@ -174,33 +174,27 @@ WITH recent AS ( SELECT employee_id, - rating, review_date, ROW_NUMBER() OVER ( PARTITION BY employee_id ORDER BY review_date DESC ) AS rn, - LAG(rating) OVER ( - PARTITION BY employee_id - ORDER BY review_date DESC - ) AS prev_rating + ( + LAG(rating) OVER ( + PARTITION BY employee_id + ORDER BY review_date DESC + ) - rating + ) AS delta FROM performance_reviews - ), - deltas AS ( - SELECT - employee_id, - prev_rating - rating AS delta, - rn - FROM recent - WHERE rn > 1 AND rn <= 3 ) SELECT employee_id, name, SUM(delta) AS improvement_score FROM - deltas + recent JOIN employees USING (employee_id) +WHERE rn > 1 AND rn <= 3 GROUP BY 1 HAVING COUNT(*) = 2 AND MIN(delta) > 0 ORDER BY 3 DESC, 2; @@ -215,42 +209,38 @@ import pandas as pd def find_consistently_improving_employees( employees: pd.DataFrame, performance_reviews: pd.DataFrame ) -> pd.DataFrame: - recent = ( - performance_reviews.sort_values( - ["employee_id", "review_date"], ascending=[True, False] - ) - .groupby("employee_id") - .head(3) + performance_reviews = performance_reviews.sort_values( + ["employee_id", "review_date"], ascending=[True, False] ) - - three_reviews_ids = recent["employee_id"].value_counts().loc[lambda s: s == 3].index - recent = recent[recent["employee_id"].isin(three_reviews_ids)] - recent = recent.sort_values(["employee_id", "review_date"]) - - def strictly_increasing(ratings: pd.Series) -> bool: - return (ratings.diff().dropna() > 0).all() - - improving_ids = ( - recent.groupby("employee_id")["rating"] - .apply(strictly_increasing) - .loc[lambda s: s] - .index + performance_reviews["rn"] = ( + performance_reviews.groupby("employee_id").cumcount() + 1 ) - improving = recent[recent["employee_id"].isin(improving_ids)] - - scores = ( - improving.groupby("employee_id")["rating"] - .agg(lambda x: x.iloc[-1] - x.iloc[0]) - .reset_index(name="improvement_score") + performance_reviews["lag_rating"] = performance_reviews.groupby("employee_id")[ + "rating" + ].shift(1) + performance_reviews["delta"] = ( + performance_reviews["lag_rating"] - performance_reviews["rating"] ) - - result = ( - scores.merge(employees, on="employee_id") - .loc[:, ["employee_id", "name", "improvement_score"]] - .sort_values(["improvement_score", "name"], ascending=[False, True]) - .reset_index(drop=True) + recent = performance_reviews[ + (performance_reviews["rn"] > 1) & (performance_reviews["rn"] <= 3) + ] + improvement = ( + recent.groupby("employee_id") + .agg( + improvement_score=("delta", "sum"), + count=("delta", "count"), + min_delta=("delta", "min"), + ) + .reset_index() + ) + improvement = improvement[ + (improvement["count"] == 2) & (improvement["min_delta"] > 0) + ] + result = improvement.merge(employees[["employee_id", "name"]], on="employee_id") + result = result.sort_values( + by=["improvement_score", "name"], ascending=[False, True] ) - return result + return result[["employee_id", "name", "improvement_score"]] ``` diff --git a/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.py b/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.py index 4399478a47451..2e89b2fe0bc6d 100644 --- a/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.py +++ b/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.py @@ -4,39 +4,35 @@ def find_consistently_improving_employees( employees: pd.DataFrame, performance_reviews: pd.DataFrame ) -> pd.DataFrame: - recent = ( - performance_reviews.sort_values( - ["employee_id", "review_date"], ascending=[True, False] - ) - .groupby("employee_id") - .head(3) + performance_reviews = performance_reviews.sort_values( + ["employee_id", "review_date"], ascending=[True, False] ) - - three_reviews_ids = recent["employee_id"].value_counts().loc[lambda s: s == 3].index - recent = recent[recent["employee_id"].isin(three_reviews_ids)] - recent = recent.sort_values(["employee_id", "review_date"]) - - def strictly_increasing(ratings: pd.Series) -> bool: - return (ratings.diff().dropna() > 0).all() - - improving_ids = ( - recent.groupby("employee_id")["rating"] - .apply(strictly_increasing) - .loc[lambda s: s] - .index + performance_reviews["rn"] = ( + performance_reviews.groupby("employee_id").cumcount() + 1 ) - improving = recent[recent["employee_id"].isin(improving_ids)] - - scores = ( - improving.groupby("employee_id")["rating"] - .agg(lambda x: x.iloc[-1] - x.iloc[0]) - .reset_index(name="improvement_score") + performance_reviews["lag_rating"] = performance_reviews.groupby("employee_id")[ + "rating" + ].shift(1) + performance_reviews["delta"] = ( + performance_reviews["lag_rating"] - performance_reviews["rating"] ) - - result = ( - scores.merge(employees, on="employee_id") - .loc[:, ["employee_id", "name", "improvement_score"]] - .sort_values(["improvement_score", "name"], ascending=[False, True]) - .reset_index(drop=True) + recent = performance_reviews[ + (performance_reviews["rn"] > 1) & (performance_reviews["rn"] <= 3) + ] + improvement = ( + recent.groupby("employee_id") + .agg( + improvement_score=("delta", "sum"), + count=("delta", "count"), + min_delta=("delta", "min"), + ) + .reset_index() + ) + improvement = improvement[ + (improvement["count"] == 2) & (improvement["min_delta"] > 0) + ] + result = improvement.merge(employees[["employee_id", "name"]], on="employee_id") + result = result.sort_values( + by=["improvement_score", "name"], ascending=[False, True] ) - return result + return result[["employee_id", "name", "improvement_score"]] diff --git a/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.sql b/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.sql index d6d72fc408948..3c747c8f0eea2 100644 --- a/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.sql +++ b/solution/3500-3599/3580.Find Consistently Improving Employees/Solution.sql @@ -2,33 +2,27 @@ WITH recent AS ( SELECT employee_id, - rating, review_date, ROW_NUMBER() OVER ( PARTITION BY employee_id ORDER BY review_date DESC ) AS rn, - LAG(rating) OVER ( - PARTITION BY employee_id - ORDER BY review_date DESC - ) AS prev_rating + ( + LAG(rating) OVER ( + PARTITION BY employee_id + ORDER BY review_date DESC + ) - rating + ) AS delta FROM performance_reviews - ), - deltas AS ( - SELECT - employee_id, - prev_rating - rating AS delta, - rn - FROM recent - WHERE rn > 1 AND rn <= 3 ) SELECT employee_id, name, SUM(delta) AS improvement_score FROM - deltas + recent JOIN employees USING (employee_id) +WHERE rn > 1 AND rn <= 3 GROUP BY 1 HAVING COUNT(*) = 2 AND MIN(delta) > 0 ORDER BY 3 DESC, 2;