Dado un dataframe ‘a’ con 3 columnas, A, B, C y 3 filas de valores numéricos. ¿Cómo se clasifican todas las filas con un operador de comp usando solo el producto de A [i] * B [i]? Parece que la clasificación de los pandas solo toma columnas y luego un método de clasificación.
Me gustaría usar una función de comparación como la de abajo.
f = lambda i,j: a['A'][i]*a['B'][i] < a['A'][j]*a['B'][j]
Hay al menos dos formas:
Método 1
Di que empiezas con
In [175]: df = pd.DataFrame({'A': [1, 2], 'B': [1, -1], 'C': [1, 1]})
Puede agregar una columna que es su clave de clasificación
In [176]: df['sort_val'] = df.A * df.B
Finalmente ordenar por él y soltarlo.
In [190]: df.sort_values('sort_val').drop('sort_val', 1) Out[190]: ABC 1 2 -1 1 0 1 1 1
Método 2
Use numpy.argsort
y luego use .ix
en los índices resultantes:
In [197]: import numpy as np In [198]: df.ix[np.argsort(df.A * df.B).values] Out[198]: ABC 0 1 1 1 1 2 -1 1
Otra forma, agregándolo aquí porque este es el primer resultado en Google:
df.loc[(df.A * df.B).sort_values().index]
Esto funciona bien para mí y es bastante sencillo. La respuesta de @Ami Tavory me dio resultados extraños con un índice categórico; aunque no estoy seguro de que sea por eso.
Simplemente agregando a @srs super elegante responda una opción iloc
con algunas comparaciones de tiempo con loc
y la solución ingenua.
(Se prefiere iloc para cuando su índice se base en la posición (frente a la etiqueta para loc)
import numpy as np import pandas as pd N = 10000 df = pd.DataFrame({ 'A': np.random.randint(low=1, high=N, size=N), 'B': np.random.randint(low=1, high=N, size=N) }) %%timeit -n 100 df['C'] = df['A'] * df['B'] df.sort_values(by='C')
naive: 100 bucles, lo mejor de 3: 1.85 ms por bucle
%%timeit -n 100 df.loc[(df.A * df.B).sort_values().index]
loc: 100 bucles, el mejor de 3: 2.69 ms por bucle
%%timeit -n 100 df.iloc[(df.A * df.B).sort_values().index]
iloc: 100 bucles, lo mejor de 3: 2.02 ms por bucle
df['C'] = df['A'] * df['B'] df1 = df.sort_values(by='C') df2 = df.loc[(df.A * df.B).sort_values().index] df3 = df.iloc[(df.A * df.B).sort_values().index] print np.array_equal(df1.index, df2.index) print np.array_equal(df2.index, df3.index)
Resultados de las pruebas (comparando el orden del índice completo) entre todas las opciones:
Cierto
Cierto