¿Cómo ordenar un DataFrame en pandas python por dos o más columnas?

Supongamos que tengo un dataframe con las columnas a , c , quiero ordenar el dataframe por la columna b en orden ascendente y por la columna c en orden descendente, ¿cómo hago esto?

A partir de la versión 0.17.0, el método de sort quedó en desuso en favor de sort_values . sort fue eliminado completamente en la versión 0.20.0. Los argumentos (y resultados) siguen siendo los mismos:

 df.sort_values(['a', 'b'], ascending=[True, False]) 

Puedes usar el argumento ascendente de sort :

 df.sort(['a', 'b'], ascending=[True, False]) 

Por ejemplo:

 In [11]: df1 = pd.DataFrame(np.random.randint(1, 5, (10,2)), columns=['a','b']) In [12]: df1.sort(['a', 'b'], ascending=[True, False]) Out[12]: ab 2 1 4 7 1 3 1 1 2 3 1 2 4 3 2 6 4 4 0 4 3 9 4 3 5 4 1 8 4 1 

Según lo comentado por @renadeen

Ordenar no está en su lugar por defecto! Por lo tanto, debe asignar el resultado del método de clasificación a una variable o agregar inplace = True a la llamada al método.

es decir, si desea reutilizar df1 como un DataFrame ordenado:

 df1 = df1.sort(['a', 'b'], ascending=[True, False]) 

o

 df1.sort(['a', 'b'], ascending=[True, False], inplace=True) 

A partir de pandas 0.17.0, DataFrame.sort() está en desuso y se configura para eliminarse en una versión futura de pandas. La forma de ordenar un dataframe por sus valores es ahora DataFrame.sort_values

Como tal, la respuesta a su pregunta ahora sería

 df.sort_values(['b', 'c'], ascending=[True, False], inplace=True) 

Para grandes marcos de datos de datos numéricos, puede ver una mejora significativa en el rendimiento a través de numpy.lexsort , que realiza una ordenación indirecta utilizando una secuencia de teclas:

 import pandas as pd import numpy as np np.random.seed(0) df1 = pd.DataFrame(np.random.randint(1, 5, (10,2)), columns=['a','b']) df1 = pd.concat([df1]*100000) def pdsort(df1): return df1.sort_values(['a', 'b'], ascending=[True, False]) def lex(df1): arr = df1.values return pd.DataFrame(arr[np.lexsort((-arr[:, 1], arr[:, 0]))]) assert (pdsort(df1).values == lex(df1).values).all() %timeit pdsort(df1) # 193 ms per loop %timeit lex(df1) # 143 ms per loop 

Una peculiaridad es que el orden de clasificación definido con numpy.lexsort se invierte: (-'b', 'a') ordena por series a primero. Negamos la serie b para reflejar queremos esta serie en orden descendente.