Estoy tratando de clasificar un marco de datos de pandas en función de dos columnas. Puedo clasificarlo en función de una columna, pero ¿cómo puedo clasificarlo en función de dos columnas? 'SaleCount', luego 'TotalRevenue'?
import pandas as pd df = pd.DataFrame({'TotalRevenue':[300,9000,1000,750,500,2000,0,600,50,500], 'Date':['2016-12-02' for i in range(10)], 'SaleCount':[10,100,30,35,20,100,0,30,2,20], 'shops':['S3','S2','S1','S5','S4','S8','S6','S7','S9','S10']}) 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)salida de corriente:
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 7Estoy tratando de generar una salida como esta:
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 9La forma genérica de hacerlo es agrupar los campos deseados en una tupla, sean del tipo que sean.
df["Rank"] = df[["SaleCount","TotalRevenue"]].apply(tuple,axis=1)\ .rank(method='dense',ascending=False).astype(int) df.sort_values("Rank") TotalRevenue Date SaleCount shops Rank 1 9000 2016-12-02 100 S2 1 5 2000 2016-12-02 100 S8 2 3 750 2016-12-02 35 S5 3 2 1000 2016-12-02 30 S1 4 7 600 2016-12-02 30 S7 5 4 500 2016-12-02 20 S4 6 9 500 2016-12-02 20 S10 6 0 300 2016-12-02 10 S3 7 8 50 2016-12-02 2 S9 8 6 0 2016-12-02 0 S6 9pd.factorize generará valores únicos para cada elemento único de un iterable. Solo necesitamos clasificar en el orden que nos gustaría y luego factorizar. Para hacer varias columnas, convertimos el resultado ordenado en tuplas.
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 9Otra forma sería convertir ambas columnas de interés en str y combinarlas concatenándolas. Conviértalos nuevamente a valores numéricos para que puedan diferenciarse en función de su magnitud.
En method=dense , los rangos de valores duplicados permanecerían sin cambios. (Aquí: 6)
Dado que desea clasificarlos en orden descendente, especificar ascending=False en Series.rank() le permitiría lograr el resultado deseado.
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')