Ranking. col.rank(ascending=False) gives 1 to the largest value. Ties need a rule, set with method=:
"average" (the default): two values tied for 2nd both get 2.5.
"min": both get 2, and the next value gets 4 (like sports tables).
"dense": both get 2, and the next gets 3.
"first": ties are broken by order in the table.
df.groupby("dept")["salary"].rank(...) ranks within each group.
Running values. cumsum() is a running total, and cummax() a running maximum; both accept a groupby in front for one running total per group. groupby(...).cumcount() numbers the rows within each group from 0, so add 1 for "first order, second order...".
These need the rows in the right order, so sort by date first if they're not.