2017-02-01 2 views
3

Я пытаюсь ранжировать рамку данных pandas на основе двух столбцов. я ранжировать его на основе одного столбца, но как я могу причислить его основано на двух колонкахPandas rank несколькими столбцами

import pandas as pd 


sales = [10,100,30,35,20,100,0,30,2,20] 
rev = [300,9000,1000,750,500,2000,0,600,50,500] 
shops = ['S3', 'S2', 'S1', 'S5' ,'S4', 'S8', 'S6', 'S7', 'S9', 'S10'] 
#rng = pd.date_range(start='12/1/2016', end='12/10/2016') 
dates = ['2016-12-02' for i in range(10)] 
df = pd.DataFrame({'TotalRevenue':rev, 'Date':dates, 'SaleCount':sales, 'shops':shops}) 

df['Rank'] = df.SaleCount.rank(method='dense',ascending = False).astype(int) 

#df['Rank'] = df.TotalRevenue.rank(method='dense',ascending = False).astype(int) 
df.sort_values(['Rank'], inplace=True) 

print(df) 

выходной ток:

Date  SaleCount TotalRevenue shops Rank 
1 2016-12-02 100   9000   S2  1 
5 2016-12-06 100   2000   S8  1 
3 2016-12-04 35   750    S5  2 
2 2016-12-03 30   1000   S1  3 
7 2016-12-08 30   600    S7  3 
9 2016-12-10 20   500    S10  4 
4 2016-12-05 20   500    S4  4 
0 2016-12-01 10   300    S3  5 
8 2016-12-09 2   50    S9  6 
6 2016-12-07 0   0    S6  7 

Я пытаюсь создать выход так:

Date  SaleCount TotalRevenue shops Rank 
1 2016-12-02 100   9000   S2  1 
5 2016-12-02 100   2000   S8  2 
3 2016-12-02 35   750    S5  3 
2 2016-12-02 30   1000   S1  4 
7 2016-12-02 30   600    S7  5 
9 2016-12-02 20   500    S10  6 
4 2016-12-02 20   500    S4  6 
0 2016-12-02 10   300    S3  7 
8 2016-12-02 2   50    S9  8 
6 2016-12-02 0   0    S6  9 

заранее спасибо

ответ

5

Другой способ ввести литье под давлением как столбцы, представляющие интерес для str и объединить их конкатенации их. Преобразуйте их обратно в числовые значения, чтобы их можно было дифференцировать в зависимости от их величины.

В method=dense разряды дублированных значений останутся неизменными. (Здесь: 6)

Поскольку вы хотите ранжировать их в порядке убывания, указав ascending=False в Series.rank(), вы получите желаемый результат.

col1 = df["SaleCount"].astype(str) 
col2 = df["TotalRevenue"].astype(str) 
df['Rank'] = (col1+col2).astype(int).rank(method='dense', ascending=False).astype(int) 
df.sort_values('Rank') 

enter image description here

+0

Да, это так. В противном случае «rank» не сможет назначать группы по их величине. –

+0

да! хорошее решение. – piRSquared

+0

@piRSquared: Большое спасибо :-) –

4

pd.factorize будет генерировать уникальный ва для каждого уникального элемента итерации. Нам нужно сортировать только в том порядке, который нам бы хотелось, а затем разложить факторизацию. Чтобы сделать несколько столбцов, мы преобразуем отсортированный результат в кортежи.

cols = ['SaleCount', 'TotalRevenue'] 
tups = df[cols].sort_values(cols, ascending=False).apply(tuple, 1) 
f, i = pd.factorize(tups) 
factorized = pd.Series(f + 1, tups.index) 

df.assign(Rank=factorized) 

     Date SaleCount TotalRevenue shops Rank 
1 2016-12-02  100   9000 S2  1 
5 2016-12-02  100   2000 S8  2 
3 2016-12-02   35   750 S5  3 
2 2016-12-02   30   1000 S1  4 
7 2016-12-02   30   600 S7  5 
4 2016-12-02   20   500 S4  6 
9 2016-12-02   20   500 S10  6 
0 2016-12-02   10   300 S3  7 
8 2016-12-02   2   50 S9  8 
6 2016-12-02   0    0 S6  9 
Смежные вопросы