Ранжирование строк фрейма данных pandas по нескольким столбцам

#pandas #ranking

#pandas #Рейтинг

Вопрос:

Я новичок в Pandas. Я пытаюсь понять, как сделать что-то в pandas, что я делаю в SQL —

У меня есть таблица, подобная —

 Account Company Blotter
112233  10      62
233445  12      62
233445  10      66
343454  21      66
343454  21      64
768876  25      54
 

В SQL, если данная учетная запись отображается в нескольких строках, я бы использовал rank(), и если я хочу отдать предпочтение определенной компании, я бы поместил оператор case, чтобы заставить эту компанию быть приоритетной. Я также могу использовать столбец Blotter в качестве дополнительного параметра ранга.
например

 rank() over(
    partition by ACCOUNT 
    order by case 
                when COMPANY='12' then 0 
                when COMPANY='21' then 1 
                else COMPANY 
             end, 
             case 
                when BLOTTER ='66' then 0 
                else BLOTTER 
             end
)
 

ожидаемый результат:

    Account  Company  Blotter  rank
0   112233       10       62     1
1   233445       12       62     1
2   233445       10       66     2
3   343454       21       66     1
4   343454       21       64     2
5   768876       25       54     1
 

Комментарии:

1. пожалуйста, опубликуйте ожидаемый результат

2. Пожалуйста, опубликуйте ожидаемый результат.

Ответ №1:

Возможно, вы захотите попробовать это:

 # recompute the sort criteria for company and blotter
ser_sort_company= df['Company'].map({12: 0, 21: 1}).fillna(df['Company'])
ser_sort_blotter= df['Blotter'].map({12: 0, 21: 1}).fillna(df['Blotter'])
df['rank']= (df
     # temporarily create sort columns
     .assign(sort_company=ser_sort_company)
     .assign(sort_blotter=ser_sort_blotter)
     # temporarily sort the result
     # this replaces the ORDER BY part
     .sort_values(['sort_company', 'sort_blotter'])
     # group by Account to replace the PARTITION BY part
     .groupby('Account')
     # get the position of the record in the group (RANK part)
     .transform('cumcount')   1
)

df
 

Он оценивает, чтобы:

    Account  Company  Blotter  rank
0   112233       10       62     1
1   233445       12       62     1
2   233445       10       66     2
3   343454       21       66     2
4   343454       21       64     1
5   768876       25       54     1
 

Комментарии:

1. Большое тебе спасибо @jottbe. Очень простое решение, работает идеально!!

2. Рад, что смог помочь. Если хотите, вы можете пометить это как ответ.

Ответ №2:

метод pandas sort_values для фрейма данных может быть тем, что вы ищете.

 import pandas as pd

data = [
[112233, 10, 62],
[233445, 12, 62],
[233445, 10, 66],
[343454, 21, 66],
[343454, 21, 64],
[768876, 25, 54]]

df = pd.DataFrame(data, columns=['Account', 'Company', 'Blotter'])
df
 
    Account  Company Blotter
0   112233  10  62
1   233445  12  62
2   233445  10  66
3   343454  21  66
4   343454  21  64
5   768876  25  54
 
 df_shuffled = df.sample(frac=1, random_state=0)   # shuffle the rows
df_shuffled
 
     Account Company Blotter
5   768876  25  54
2   233445  10  66
1   233445  12  62
3   343454  21  66
0   112233  10  62
4   343454  21  64
 
 df_shuffled.sort_values(by=['Account', 'Company', 'Blotter'], 
                        ascending=[True, False, False])
 
     Account Company Blotter
0   112233  10  62
1   233445  12  62
2   233445  10  66
3   343454  21  66
4   343454  21  64
5   768876  25  54