2012-06-16 25 views
134

Tengo un dataframe con más de 200 columnas (no preguntes por qué). La cuestión es, ya que se generaron el orden sePython Pandas - Reordenamiento de columnas en un marco de datos basado en el nombre de la columna

['Q1.3','Q6.1','Q1.2','Q1.1',......] 

tengo que volver a ordenar las columnas de la siguiente manera:

['Q1.1','Q1.2','Q1.3',.....'Q6.1',......] 

¿Hay alguna manera para mí para hacer esto dentro de pitón?

+16

Por qué ¿tienes 200 columnas? ;) –

+0

Posible duplicado de [¿Cómo cambiar el orden de las columnas de DataFrame?] (Https://stackoverflow.com/questions/13148429/how-to-change-the-order-of-dataframe-columns) –

Respuesta

171
df.reindex_axis(sorted(df.columns), axis=1) 

Esto supone que la ordenación de los nombres de las columnas dará el orden que desee. Si los nombres de sus columnas no se ordenan lexicográficamente (por ejemplo, si desea que la columna Q10.3 aparezca después de Q9.1), deberá ordenar de forma diferente, pero eso no tiene nada que ver con los pandas.

+2

Me gusta porque el mismo método se puede usar para ordenar filas (necesitaba ordenar filas y columnas). Si bien es el mismo método, puede omitir el argumento 'axis' (o proporcionar su valor predeterminado,' 0'), como 'df.reindex_axis (sorted (non_sorted_row_index))' que es equivalente a 'df.reindex (sorted (non_sorted_row_index))) ' –

+0

Tenga en cuenta que la reindexación no se realiza en el lugar, por lo que para aplicar el ordenamiento al df, debe usar' df = df.reindex_axis (...) '. Además, tenga en cuenta que los géneros no lexicográficos son fáciles con este enfoque, ya que la lista de nombres de columnas puede ordenarse por separado en un orden arbitrario y luego pasarse a 'reindex_axis'. Esto no es posible con el enfoque alternativo sugerido por @Wes McKinney ('df = df.sort_index (axis = 1)'), que sin embargo es más limpio para los géneros lexicográficos puros. – WhoIsJack

0

El sort método y sorted función le permiten ofrecer una función personalizada para extraer la clave utilizada para la comparación:

>>> ls = ['Q1.3', 'Q6.1', 'Q1.2'] 
>>> sorted(ls, key=lambda x: float(x[1:])) 
['Q1.2', 'Q1.3', 'Q6.1'] 
+0

Esto funciona para listas en general y estoy familiarizado con él. ¿Cómo lo aplico a un DataFrame de pandas? – pythOnometrist

+1

No estoy seguro, admito que mi respuesta no era específica de esta biblioteca. – tweet

186

También se puede hacer de forma más sucinta:

df.sort_index(axis=1)

Editar:

Asegúrate de que mantener el valor

df = df.sort_index(axis=1)

o hacerlo en su lugar

df.sort_index(axis=1, inplace=True)

+2

recuerde hacer 'df = df.sort_index (axis = 1)', por @multigoodverse – GoJian

+5

o modifique 'df' in-place con' df.sort_index (axis = 1, inplace = True) ' – Jakub

+1

Esto debería ser # 1 –

16

Tweet's answer se puede pasar a la respuesta de BrenBarn anterior con

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1) 

Así, por tu ejemplo, decir:

vals = randint(low=16, high=80, size=25).reshape(5,5) 
cols = ['Q1.3', 'Q6.1', 'Q1.2', 'Q9.1', 'Q10.2'] 
data = DataFrame(vals, columns = cols) 

Se obtiene:

data 

    Q1.3 Q6.1 Q1.2 Q9.1 Q10.2 
0 73  29  63  51  72 
1 61  29  32  68  57 
2 36  49  76  18  37 
3 63  61  51  30  31 
4 36  66  71  24  77 

Luego hacer:

data.reindex_axis(sorted(data.columns, key=lambda x: float(x[1:])), axis=1) 

lo que resulta en:

data 


    Q1.2 Q1.3 Q6.1 Q9.1 Q10.2 
0 2  0  1  3  4 
1 7  5  6  8  9 
2 2  0  1  3  4 
3 2  0  1  3  4 
4 2  0  1  3  4 
20

Sólo puede hacer:

 
df[sorted(df.columns)] 
+1

obtengo el objeto "'DataFrame' no se puede llamar" para esto. Versión: pandas 0.14. – multigoodverse

13

No olvide agregar "inplace = True" a la respuesta de Wes o establecer el resultado en un nuevo DataFrame.

df.sort_index(axis=1, inplace=True) 
3

El método más rápido es:

df.sort_index(axis=1) 

Tenga en cuenta que esto crea una nueva instancia.Por lo tanto necesita almacenar el resultado en una nueva variable:

sortedDf=df.sort_index(axis=1) 
-1
print df.sort_index(by='Frequency',ascending=False) 

donde se encuentra el nombre de la columna, si desea ordenar el conjunto de datos sobre la base de la columna

9

Si necesita un arbitraria en lugar de la secuencia ordenada secuencia, se podría hacer:

sequence = ['Q1.1','Q1.2','Q1.3',.....'Q6.1',......] 
your_dataframe = your_dataframe.reindex(columns=sequence) 

he probado esto en 2.7.10 y funcionó para mí.

5

Durante varias columnas, puede poner columnas de orden lo que quiere:

#['A', 'B', 'C'] <-this is your columns order 
df = df[['C', 'B', 'A']] 

Este ejemplo muestra la clasificación y cortar columnas:

d = {'col1':[1, 2, 3], 'col2':[4, 5, 6], 'col3':[7, 8, 9], 'col4':[17, 18, 19]} 
df = pandas.DataFrame(d) 

que se obtiene:

col1 col2 col3 col4 
1  4  7 17 
2  5  8 18 
3  6  9 19 

Entonces do:

df = df[['col3', 'col2', 'col1']] 

El resultado es:

col3 col2 col1 
7  4  1 
8  5  2 
9  6  3  
0

Un caso de uso es que se ha llamado (algunos de) sus columnas con algún prefijo, y desea que las columnas ordenados con esos prefijos todos juntos y en algún orden particular (por no alfabético).

Por ejemplo, puede comenzar todas sus funciones con Ft_, etiquetas con Lbl_, etc., y desea primero todas las columnas no prefijadas, luego todas las características, luego la etiqueta. Usted puede hacer esto con la siguiente función (que se nota un posible problema de eficiencia utilizando sum para reducir las listas, pero esto no es un problema a menos que tenga un montón de columnas, que yo no):

def sortedcols(df, groups = ['Ft_', 'Lbl_']): 
    return df[ sum([list(filter(re.compile(r).search, list(df.columns).copy())) for r in (lambda l: ['^(?!(%s))' % '|'.join(l)] + ['^%s' % i for i in l ])(groups) ], []) ] 
Cuestiones relacionadas