Skip to content

Pandas Sort Values: Guía completa para ordenar DataFrames en Python

Updated on

Los datos sin ordenar son difíciles de analizar. Recorres miles de filas intentando encontrar las ventas más altas, las fechas más recientes o las tasas de error más bajas -- y pierdes patrones que serían obvios si los datos estuvieran ordenados. Ordenar una lista de Python funciona para casos simples, pero los DataFrames tienen múltiples columnas, tipos mixtos y valores faltantes que las listas no pueden manejar.

Pandas sort_values() ordena cualquier DataFrame por una o más columnas, con control total sobre el orden ascendente/descendente, la ubicación de nulos y la estabilidad. Esta guía cubre todos los patrones de ordenación que encontrarás en el trabajo real con datos.

📚

Ordenación básica con sort_values()

Ordenar por una sola columna

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'score': [85, 92, 78, 95, 88],
    'age': [25, 30, 22, 28, 35]
})
 
# Ordenar por score (ascendente por defecto)
sorted_df = df.sort_values('score')
print(sorted_df)
#       name  score  age
# 2  Charlie     78   22
# 0    Alice     85   25
# 4      Eve     88   35
# 1      Bob     92   30
# 3    Diana     95   28

Ordenar de forma descendente

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'score': [85, 92, 78, 95, 88],
    'age': [25, 30, 22, 28, 35]
})
 
# Puntuaciones más altas primero
sorted_df = df.sort_values('score', ascending=False)
print(sorted_df)
#       name  score  age
# 3    Diana     95   28
# 1      Bob     92   30
# 4      Eve     88   35
# 0    Alice     85   25
# 2  Charlie     78   22

Ordenar en el lugar

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [85, 92, 78]
})
 
# Modificar df directamente (no se crea copia)
df.sort_values('score', inplace=True)
print(df)
#       name  score
# 2  Charlie     78
# 0    Alice     85
# 1      Bob     92

Ordenación por múltiples columnas

Ordenar por varias columnas

import pandas as pd
 
df = pd.DataFrame({
    'department': ['Sales', 'Engineering', 'Sales', 'Engineering', 'Sales'],
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'salary': [70000, 85000, 65000, 90000, 70000]
})
 
# Ordenar primero por departamento, luego por salario dentro de cada departamento
sorted_df = df.sort_values(['department', 'salary'])
print(sorted_df)
#     department     name  salary
# 1  Engineering      Bob   85000
# 3  Engineering    Diana   90000
# 2        Sales  Charlie   65000
# 0        Sales    Alice   70000
# 4        Sales      Eve   70000

Ascendente/descendente mixto

import pandas as pd
 
df = pd.DataFrame({
    'department': ['Sales', 'Engineering', 'Sales', 'Engineering', 'Sales'],
    'name': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve'],
    'salary': [70000, 85000, 65000, 90000, 70000]
})
 
# Departamento ascendente, salario descendente
sorted_df = df.sort_values(
    ['department', 'salary'],
    ascending=[True, False]
)
print(sorted_df)
#     department     name  salary
# 3  Engineering    Diana   90000
# 1  Engineering      Bob   85000
# 0        Sales    Alice   70000
# 4        Sales      Eve   70000
# 2        Sales  Charlie   65000

Manejo de valores faltantes (NaN)

Por defecto, los valores NaN van al final independientemente del orden de clasificación. Usa na_position para controlarlo:

import pandas as pd
import numpy as np
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
    'score': [85, np.nan, 78, np.nan]
})
 
# NaN al final (predeterminado)
print(df.sort_values('score'))
#       name  score
# 2  Charlie   78.0
# 0    Alice   85.0
# 1      Bob    NaN
# 3    Diana    NaN
 
# NaN al principio
print(df.sort_values('score', na_position='first'))
#       name  score
# 1      Bob    NaN
# 3    Diana    NaN
# 2  Charlie   78.0
# 0    Alice   85.0

Ordenar por índice con sort_index()

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [85, 92, 78]
}, index=[2, 0, 1])
 
# Ordenar por índice
print(df.sort_index())
#      name  score
# 0     Bob     92
# 1  Charlie    78
# 2   Alice     85
 
# Ordenar por nombres de columna (axis=1)
df2 = pd.DataFrame({
    'c': [1, 2], 'a': [3, 4], 'b': [5, 6]
})
print(df2.sort_index(axis=1))
#    a  b  c
# 0  3  5  1
# 1  4  6  2

Restablecer índice después de ordenar

Después de ordenar, se conserva el índice original. Para obtener un índice secuencial limpio:

import pandas as pd
 
df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'score': [85, 92, 78]
})
 
sorted_df = df.sort_values('score').reset_index(drop=True)
print(sorted_df)
#       name  score
# 0  Charlie     78
# 1    Alice     85
# 2      Bob     92

Usa drop=True para descartar el índice antiguo. Sin él, el índice antiguo se convierte en una columna.

Orden de clasificación personalizado

Usando tipos categóricos

import pandas as pd
 
df = pd.DataFrame({
    'priority': ['Medium', 'High', 'Low', 'High', 'Medium'],
    'task': ['Task A', 'Task B', 'Task C', 'Task D', 'Task E']
})
 
# Definir orden personalizado
priority_order = pd.CategoricalDtype(['Low', 'Medium', 'High'], ordered=True)
df['priority'] = df['priority'].astype(priority_order)
 
sorted_df = df.sort_values('priority')
print(sorted_df)
#   priority    task
# 2      Low  Task C
# 0   Medium  Task A
# 4   Medium  Task E
# 1     High  Task B
# 3     High  Task D

Usando el parámetro key

import pandas as pd
 
df = pd.DataFrame({
    'name': ['alice', 'Bob', 'CHARLIE', 'diana'],
    'score': [85, 92, 78, 95]
})
 
# Ordenación sin distinción de mayúsculas/minúsculas
sorted_df = df.sort_values('name', key=lambda x: x.str.lower())
print(sorted_df)
#       name  score
# 0    alice     85
# 1      Bob     92
# 2  CHARLIE     78
# 3    diana     95

Comparación de métodos

MétodoPropósito¿Modifica el original?Retorna
sort_values(col)Ordenar por valores de columnaNo (salvo inplace=True)DataFrame ordenado
sort_values([col1, col2])Ordenar por múltiples columnasNo (salvo inplace=True)DataFrame ordenado
sort_index()Ordenar por índice de filaNo (salvo inplace=True)DataFrame ordenado
nsmallest(n, col)Obtener n valores más pequeñosNoSubconjunto de DataFrame
nlargest(n, col)Obtener n valores más grandesNoSubconjunto de DataFrame
rank()Asignar rangos a valoresNoSeries de rangos

Consejos de rendimiento

nlargest() y nsmallest() para Top-N

Cuando solo necesitas las primeras o últimas N filas, nlargest() y nsmallest() son más rápidos que ordenar todo el DataFrame:

import pandas as pd
import numpy as np
 
# DataFrame grande
df = pd.DataFrame({
    'id': range(1_000_000),
    'value': np.random.randn(1_000_000)
})
 
# Más rápido: solo encontrar el top 10
top_10 = df.nlargest(10, 'value')
 
# Más lento: ordena todo, luego corta
top_10_slow = df.sort_values('value', ascending=False).head(10)

Ordenación estable vs. inestable

import pandas as pd
 
df = pd.DataFrame({
    'group': ['A', 'B', 'A', 'B'],
    'value': [1, 1, 2, 2],
    'order': [1, 2, 3, 4]
})
 
# Ordenación estable (predeterminada) conserva el orden original en empates
stable = df.sort_values('value', kind='mergesort')  # Predeterminado
 
# Ordenación inestable (más rápida para conjuntos de datos grandes)
unstable = df.sort_values('value', kind='quicksort')

Ejemplos prácticos

Ordenar fechas

import pandas as pd
 
df = pd.DataFrame({
    'event': ['Launch', 'Meeting', 'Deadline', 'Review'],
    'date': pd.to_datetime(['2026-03-15', '2026-01-10', '2026-02-28', '2026-01-05'])
})
 
# Orden cronológico
print(df.sort_values('date'))
#      event       date
# 3   Review 2026-01-05
# 1  Meeting 2026-01-10
# 2 Deadline 2026-02-28
# 0   Launch 2026-03-15

Ordenar con GroupBy

import pandas as pd
 
df = pd.DataFrame({
    'store': ['A', 'A', 'B', 'B', 'A', 'B'],
    'product': ['X', 'Y', 'X', 'Y', 'Z', 'Z'],
    'revenue': [100, 250, 150, 300, 200, 175]
})
 
# Producto con mayor ingreso por tienda
top_per_store = (df.sort_values('revenue', ascending=False)
                   .groupby('store')
                   .head(1))
print(top_per_store)
#   store product  revenue
# 3     B       Y      300
# 1     A       Y      250

Exploración visual de datos ordenados

Después de ordenar tu DataFrame para encontrar patrones, PyGWalker (opens in a new tab) te permite explorar los mismos datos a través de gráficos interactivos de arrastrar y soltar en Jupyter -- sin código adicional:

import pygwalker as pyg
 
walker = pyg.walk(sorted_df)

Preguntas frecuentes

¿Cómo ordeno un DataFrame por columna en pandas?

Usa df.sort_values('column_name') para orden ascendente o df.sort_values('column_name', ascending=False) para descendente. Para múltiples columnas, pasa una lista: df.sort_values(['col1', 'col2']).

¿Cómo ordeno por múltiples columnas con diferentes órdenes?

Pasa una lista de booleanos a ascending: df.sort_values(['col1', 'col2'], ascending=[True, False]). Esto ordena col1 ascendente y col2 descendente.

¿Dónde van los valores NaN al ordenar?

Por defecto, los valores NaN se colocan al final independientemente de la dirección de ordenación. Usa na_position='first' para ponerlos al principio: df.sort_values('col', na_position='first').

¿Cuál es la diferencia entre sort_values y sort_index?

sort_values() ordena por valores de columna. sort_index() ordena por el índice de fila (o índice de columna con axis=1). Usa sort_values para ordenar datos y sort_index cuando necesites filas ordenadas por sus etiquetas de índice.

¿Cómo ordeno un DataFrame en el lugar sin crear una copia?

Pasa inplace=True: df.sort_values('col', inplace=True). Esto modifica el DataFrame original y retorna None. Sin embargo, el estilo moderno de pandas prefiere la reasignación: df = df.sort_values('col').

Conclusión

sort_values() es la herramienta principal para ordenar DataFrames en pandas. Usa un nombre de columna único para ordenaciones simples, una lista para ordenaciones multicolumna y el parámetro ascending para controlar la dirección. Maneja los valores faltantes con na_position, usa nlargest()/nsmallest() para consultas Top-N y CategoricalDtype para ordenaciones personalizadas. Recuerda que la ordenación devuelve un nuevo DataFrame por defecto -- usa reset_index(drop=True) si quieres un índice secuencial limpio después.

📚