¿Cómo cambiar el orden de las columnas de DataFrame?

1174

Tengo lo siguiente DataFrame( df):

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 5))

Agrego más columnas por asignación:

df['mean'] = df.mean(1)

¿Cómo puedo mover la columna meanal frente, es decir, establecerla como primera columna dejando intacto el orden de las otras columnas?

3
1075

Una forma fácil sería reasignar el marco de datos con una lista de columnas, reorganizadas según sea necesario.

Esto es lo que tienes ahora:

In [6]: df
Out[6]:
          0         1         2         3         4      mean
0  0.445598  0.173835  0.343415  0.682252  0.582616  0.445543
1  0.881592  0.696942  0.702232  0.696724  0.373551  0.670208
2  0.662527  0.955193  0.131016  0.609548  0.804694  0.632596
3  0.260919  0.783467  0.593433  0.033426  0.512019  0.436653
4  0.131842  0.799367  0.182828  0.683330  0.019485  0.363371
5  0.498784  0.873495  0.383811  0.699289  0.480447  0.587165
6  0.388771  0.395757  0.745237  0.628406  0.784473  0.588529
7  0.147986  0.459451  0.310961  0.706435  0.100914  0.345149
8  0.394947  0.863494  0.585030  0.565944  0.356561  0.553195
9  0.689260  0.865243  0.136481  0.386582  0.730399  0.561593

In [7]: cols = df.columns.tolist()

In [8]: cols
Out[8]: [0L, 1L, 2L, 3L, 4L, 'mean']

Reorganice colsde la forma que desee. Así es como moví el último elemento a la primera posición:

In [12]: cols = cols[-1:] + cols[:-1]

In [13]: cols
Out[13]: ['mean', 0L, 1L, 2L, 3L, 4L]

Luego reordene el marco de datos de esta manera:

In [16]: df = df[cols]  #    OR    df = df.ix[:, cols]

In [17]: df
Out[17]:
       mean         0         1         2         3         4
0  0.445543  0.445598  0.173835  0.343415  0.682252  0.582616
1  0.670208  0.881592  0.696942  0.702232  0.696724  0.373551
2  0.632596  0.662527  0.955193  0.131016  0.609548  0.804694
3  0.436653  0.260919  0.783467  0.593433  0.033426  0.512019
4  0.363371  0.131842  0.799367  0.182828  0.683330  0.019485
5  0.587165  0.498784  0.873495  0.383811  0.699289  0.480447
6  0.588529  0.388771  0.395757  0.745237  0.628406  0.784473
7  0.345149  0.147986  0.459451  0.310961  0.706435  0.100914
8  0.553195  0.394947  0.863494  0.585030  0.565944  0.356561
9  0.561593  0.689260  0.865243  0.136481  0.386582  0.730399
7
  • 25
    en caso de que obtenga "no se pueden concatenar objetos 'str' y 'list'" asegúrese de [] el valor str en cols: cols = [cols [7]] + cols [: 7] + cols [8:]moeabdol 9 de enero de 2015 a las 16:59
  • 3
    @FooBar Eso no es una unión establecida, es una concatenación de dos listas ordenadas. Aman 6/10/2016 a las 22:08
  • 3
    @Aman Solo estoy señalando que su código está en desuso. El manejo de su publicación queda a su discreción. FooBar 7/10/2016 a las 6:13
  • 2
    @FooBar, el tipo de colses list; incluso permite duplicados (que se descartarán cuando se utilicen en el marco de datos). Estás pensando en Indexobjetos. alexis 28 feb 2017 a las 15:19
  • 13
    Esto implica copiar TODOS los datos, lo cual es muy ineficiente. Ojalá los pandas tuvieran una forma de hacer eso sin crear una copia. Konstantin 27/11/2017 a las 8:48
627

También puedes hacer algo como esto:

df = df[['mean', '0', '1', '2', '3']]

Puede obtener la lista de columnas con:

cols = list(df.columns.values)

La salida producirá:

['0', '1', '2', '3', 'mean']

... que luego es fácil de reorganizar manualmente antes de colocarlo en la primera función

7
  • 9
    También puede obtener la lista de columnas con list (df.columns)Jim 9/10/15 a las 22:14
  • 18
    odf.columns.tolist()Jim 9/10/15 a las 22:22
  • Para los novatos como yo, reorganice la lista que obtiene de cols. Entonces df = df [cols], es decir, la lista reorganizada se coloca en la primera expresión sin un solo conjunto de corchetes. Sid 20/03/18 a las 15:18
  • 4
    No creo que esta sea una buena respuesta, ya que no proporciona código sobre cómo cambiar el orden de las columnas de ningún marco de datos. Digamos que importo un archivo csv como pandas pd como pd.read_csv(). ¿Cómo se puede utilizar su respuesta para cambiar el orden de las columnas? Robvh 25/07/19 a las 8:22
  • 2
    @Robvh, la segunda línea de código explica cómo obtener los nombres de las columnas existentes. Desde allí, puede copiar la salida en la primera línea de código y reorganizarla como desee. La única otra información que debe saber es que sin un encabezado, los nombres de columna predeterminados son números enteros, no cadenas. daniel brandstetter 9/09/19 a las 23:27
359

Simplemente asigne los nombres de las columnas en el orden que desee:

In [39]: df
Out[39]: 
          0         1         2         3         4  mean
0  0.172742  0.915661  0.043387  0.712833  0.190717     1
1  0.128186  0.424771  0.590779  0.771080  0.617472     1
2  0.125709  0.085894  0.989798  0.829491  0.155563     1
3  0.742578  0.104061  0.299708  0.616751  0.951802     1
4  0.721118  0.528156  0.421360  0.105886  0.322311     1
5  0.900878  0.082047  0.224656  0.195162  0.736652     1
6  0.897832  0.558108  0.318016  0.586563  0.507564     1
7  0.027178  0.375183  0.930248  0.921786  0.337060     1
8  0.763028  0.182905  0.931756  0.110675  0.423398     1
9  0.848996  0.310562  0.140873  0.304561  0.417808     1

In [40]: df = df[['mean', 4,3,2,1]]

Ahora, la columna 'media' aparece al frente:

In [41]: df
Out[41]: 
   mean         4         3         2         1
0     1  0.190717  0.712833  0.043387  0.915661
1     1  0.617472  0.771080  0.590779  0.424771
2     1  0.155563  0.829491  0.989798  0.085894
3     1  0.951802  0.616751  0.299708  0.104061
4     1  0.322311  0.105886  0.421360  0.528156
5     1  0.736652  0.195162  0.224656  0.082047
6     1  0.507564  0.586563  0.318016  0.558108
7     1  0.337060  0.921786  0.930248  0.375183
8     1  0.423398  0.110675  0.931756  0.182905
9     1  0.417808  0.304561  0.140873  0.310562
5
  • 10
    ¿Hace una copia? user3226167 2 de junio de 2017 a las 2:02
  • 34
    @NicholasMorley: esta no es la mejor respuesta si tiene, digamos, 1000 columnas en su df. AGS 21/07/2017 a las 20:19
  • 1
    no parece que estés asignando lo <df>.columnsque reclamas inicialmente3pitt 19/02/18 a las 19:09
  • 9
    Ésta es la mejor respuesta para una pequeña cantidad de columnas. Dongkyu Choi 19/04/18 a las 23:12
  • 6
    Esta es solo una copia de la respuesta anterior de @freddygv. Esa debería ser la respuesta aceptada, no esta. James Hirschorn 4 de mayo de 2018 a las 21:40
182

Qué tal si:

df.insert(0, 'mean', df['mean'])

http://pandas.pydata.org/pandas-docs/stable/dsintro.html#column-selection-addition-deletion

8
  • 54
    ¿Podría ser esta una característica futura agregada pandas? algo como df.move(0,df.mean)? jason 27 de mayo de 2014 a las 1:23
  • 5
    Hermosa. Y también sucede en el lugar. cucu8 2/08/18 a las 10:29
  • 3
    Esta es una solución escalable, ya que otras soluciones escriben manualmente los nombres de las columnas. CKM 19/08/19 a las 17:00
  • 6
    Esto funciona para la pregunta del OP, al crear una nueva columna, pero no para mover una columna; intentar mover los resultados en*** ValueError: cannot insert mean, already existsspinup 24 feb 2020 a las 21:07
  • 5
    Ésta es una solución limpia. El método API moderno es: df.insert(0, 'mean', df['mean'])Sumanth Lazarus 29/07/20 a las 5:22
161

En tu caso,

df = df.reindex(columns=['mean',0,1,2,3,4])

hará exactamente lo que quieras.

En mi caso (forma general):

df = df.reindex(columns=sorted(df.columns))
df = df.reindex(columns=(['opened'] + list([a for a in df.columns if a != 'opened']) ))
2
  • 2
    Traté de configurar, copy=Falsepero parece que reindex_axistodavía crea una copia. Konstantin 27 nov 2017 a las 9:10
  • 1
    @Konstantin ¿puedes crear otra pregunta sobre este tema? Sería mejor tener más contextoAlvaro Joao 27/11/2017 a las 14:11
80
import numpy as np
import pandas as pd
df = pd.DataFrame()
column_names = ['x','y','z','mean']
for col in column_names: 
    df[col] = np.random.randint(0,100, size=10000)

Puede probar las siguientes soluciones:

Solución 1:

df = df[ ['mean'] + [ col for col in df.columns if col != 'mean' ] ]

Solucion 2:


df = df[['mean', 'x', 'y', 'z']]

Solución 3:

col = df.pop("mean")
df = df.insert(0, col.name, col)

Solución 4:

df.set_index(df.columns[-1], inplace=True)
df.reset_index(inplace=True)

Solución 5:

cols = list(df)
cols = [cols[-1]] + cols[:-1]
df = df[cols]

solución 6:

order = [1,2,3,0] # setting column's order
df = df[[df.columns[i] for i in order]]

Comparación de tiempo:

Solución 1:

CPU times: user 1.05 ms, sys: 35 µs, total: 1.08 ms Wall time: 995 µs

Solucion 2 :

CPU times: user 933 µs, sys: 0 ns, total: 933 µs Wall time: 800 µs

Solución 3 :

CPU times: user 0 ns, sys: 1.35 ms, total: 1.35 ms Wall time: 1.08 ms

Solución 4 :

CPU times: user 1.23 ms, sys: 45 µs, total: 1.27 ms Wall time: 986 µs

Solución 5 :

CPU times: user 1.09 ms, sys: 19 µs, total: 1.11 ms Wall time: 949 µs

Solución 6 :

CPU times: user 955 µs, sys: 34 µs, total: 989 µs Wall time: 859 µs

6
  • 2
    la solución 1 es lo que necesitaba ya que tengo demasiadas columnas (53), graciasratnesh 1/04/20 a las 13:15
  • 2
    @Pygirl ¿Qué valor muestra el tiempo real consumido? (usuario, sistema, tiempo total o de pared)sergzemsk 10/04/20 a las 21:46
  • 2
    Esta es para mí la mejor respuesta al problema. Tantas soluciones (incluida una que necesitaba) y enfoque simple. ¡Gracias! Gustavo Rottgering 15 de mayo de 2020 a las 0:36
  • 2
    Solución 6 (sin comprensión de listas):df = df.iloc[:, [1, 2, 3, 0]]Dmitriy Work 20 de mayo de 2020 a las 16:55
  • 2
    @sergzemsk: stackoverflow.com/a/55702033/6660373 . Comparo por tiempo de pared. Pygirl 29 de septiembre de 2020 a las 4:58
80

Necesita crear una nueva lista de sus columnas en el orden deseado, luego usar df = df[cols]para reorganizar las columnas en este nuevo orden.

cols = ['mean']  + [col for col in df if col != 'mean']
df = df[cols]

También puede utilizar un enfoque más general. En este ejemplo, la última columna (indicada por -1) se inserta como la primera columna.

cols = [df.columns[-1]] + [col for col in df if col != df.columns[-1]]
df = df[cols]

También puede utilizar este enfoque para reordenar las columnas en el orden deseado si están presentes en el DataFrame.

inserted_cols = ['a', 'b', 'c']
cols = ([col for col in inserted_cols if col in df] 
        + [col for col in df if col not in inserted_cols])
df = df[cols]
0
55

Suponga que tiene dfcolumnas A B C.

La forma más sencilla es:

df = df.reindex(['B','C','A'], axis=1)
4
  • ¡Una gran cosa acerca de esta opción es que puede usarla en operaciones de tubería pandas! cheevahagadog 23/09/20 a las 15:29
  • Tenga en cuenta que esto solo devolverá un marco de datos reindexado, no cambiará la dfinstancia que se está utilizando. Si desea utilizar el df indexar, basta con utilizar el valor devuelto: df2 = df.reindex(['B', 'C', 'A'], axis=1). ¡Gracias por esta respuesta! Andreas Forslöw 8 dic.20 a las 9:13
  • cheevahagadog ¡Buen punto! liangli 25 feb a las 3:04
  • @ AndreasForslöw Gracias por resaltar eso. liangli 25 feb a las 3:05
53

Si los nombres de sus columnas son demasiado largos para escribirlos, puede especificar el nuevo orden a través de una lista de números enteros con las posiciones:

Datos:

          0         1         2         3         4      mean
0  0.397312  0.361846  0.719802  0.575223  0.449205  0.500678
1  0.287256  0.522337  0.992154  0.584221  0.042739  0.485741
2  0.884812  0.464172  0.149296  0.167698  0.793634  0.491923
3  0.656891  0.500179  0.046006  0.862769  0.651065  0.543382
4  0.673702  0.223489  0.438760  0.468954  0.308509  0.422683
5  0.764020  0.093050  0.100932  0.572475  0.416471  0.389390
6  0.259181  0.248186  0.626101  0.556980  0.559413  0.449972
7  0.400591  0.075461  0.096072  0.308755  0.157078  0.207592
8  0.639745  0.368987  0.340573  0.997547  0.011892  0.471749
9  0.050582  0.714160  0.168839  0.899230  0.359690  0.438500

Ejemplo genérico:

new_order = [3,2,1,4,5,0]
print(df[df.columns[new_order]])  

          3         2         1         4      mean         0
0  0.575223  0.719802  0.361846  0.449205  0.500678  0.397312
1  0.584221  0.992154  0.522337  0.042739  0.485741  0.287256
2  0.167698  0.149296  0.464172  0.793634  0.491923  0.884812
3  0.862769  0.046006  0.500179  0.651065  0.543382  0.656891
4  0.468954  0.438760  0.223489  0.308509  0.422683  0.673702
5  0.572475  0.100932  0.093050  0.416471  0.389390  0.764020
6  0.556980  0.626101  0.248186  0.559413  0.449972  0.259181
7  0.308755  0.096072  0.075461  0.157078  0.207592  0.400591
8  0.997547  0.340573  0.368987  0.011892  0.471749  0.639745
9  0.899230  0.168839  0.714160  0.359690  0.438500  0.050582

Aunque puede parecer que estoy escribiendo explícitamente los nombres de las columnas en un orden diferente, el hecho de que haya una columna 'media' debería dejar en claro que se new_orderrelaciona con las posiciones reales y no con los nombres de las columnas.

Para el caso específico de la pregunta de OP:

new_order = [-1,0,1,2,3,4]
df = df[df.columns[new_order]]
print(df)

       mean         0         1         2         3         4
0  0.500678  0.397312  0.361846  0.719802  0.575223  0.449205
1  0.485741  0.287256  0.522337  0.992154  0.584221  0.042739
2  0.491923  0.884812  0.464172  0.149296  0.167698  0.793634
3  0.543382  0.656891  0.500179  0.046006  0.862769  0.651065
4  0.422683  0.673702  0.223489  0.438760  0.468954  0.308509
5  0.389390  0.764020  0.093050  0.100932  0.572475  0.416471
6  0.449972  0.259181  0.248186  0.626101  0.556980  0.559413
7  0.207592  0.400591  0.075461  0.096072  0.308755  0.157078
8  0.471749  0.639745  0.368987  0.340573  0.997547  0.011892
9  0.438500  0.050582  0.714160  0.168839  0.899230  0.359690

El principal problema con este enfoque es que llamar al mismo código varias veces creará resultados diferentes cada vez, por lo que hay que tener cuidado :)

33

Esta pregunta ha sido respondida antes, pero reindex_axisahora está en desuso, por lo que sugeriría usar:

df = df.reindex(sorted(df.columns), axis=1)

Para aquellos que desean especificar el orden que desean en lugar de simplemente ordenarlos, aquí está la solución detallada:

df = df.reindex(['the','order','you','want'], axis=1)

Ahora bien, cómo desea ordenar la lista de nombres de columna realmente no es una pandaspregunta, esa es una pregunta de manipulación de la lista de Python. Hay muchas formas de hacerlo, y creo que esta respuesta tiene una forma muy ordenada de hacerlo.

5
  • 21
    No, eso es diferente. Allí, el usuario quiere ordenar todas las columnas por nombre. Aquí quieren mover una columna a la primera columna sin modificar el orden de las otras columnas. smci 17/04/13 a las 13:06
  • 2
    ¿Qué pasa si no los quiere ordenados? Chankey Pathak 8 de junio de 2017 a las 10:16
  • La respuesta no aborda el problema de la pregunta. mins 15 dic.20 a las 9:51
  • 1
    @mins Espero que la edición anterior sea lo suficientemente clara. :)dmvianna 16 dic.20 a las 0:14
  • Su edición ahora muestra una solución funcional al problema. Gracias. mins 16 dic.20 a las 10:30
23

Creo que esta es una solución un poco más ordenada:

df.insert(0, 'mean', df.pop("mean"))

Esta solución es algo similar a la solución de @JoeHeffer, pero esta es una línea.

Aquí eliminamos la columna "mean"del marco de datos y la adjuntamos al índice 0con el mismo nombre de columna.

2
  • esto es bueno, pero ¿y si quieres que termine? Roko Mijic 12/06/20 a las 12:11
  • 1
    Cualquier columna nueva que cree se agrega al final, así que supongo que seríadf["mean"] = df.pop("mean")erncyp 12/06/20 a las 15:55
19

Yo mismo me encontré con una pregunta similar y solo quería agregar lo que me decidí. Me gustó el reindex_axis() methodpara cambiar el orden de las columnas. Esto funcionó:

df = df.reindex_axis(['mean'] + list(df.columns[:-1]), axis=1)

Un método alternativo basado en el comentario de @Jorge:

df = df.reindex(columns=['mean'] + list(df.columns[:-1]))

Aunque reindex_axisparece ser un poco más rápido en micro benchmarks que reindex, creo que prefiero este último por su franqueza.

2
  • 7
    Esta fue una buena solución, pero reindex_axis quedará obsoleto. Usé reindexar y funcionó bien. Jorge 8/08/18 a las 21:32
  • Es posible que me pierda algo, pero 1 / probablemente olvidó incluir axis=1en esta segunda solución para usar las columnas, no las filas. 2 / En 2020, la reindexsolución cambia el orden de filas / columnas, pero también borra los datos (en NaNtodas partes). mins 15 dic.20 a las 10:30
18

Esta función le evita tener que enumerar todas las variables en su conjunto de datos solo para ordenar algunas de ellas.

def order(frame,var):
    if type(var) is str:
        var = [var] #let the command take a string or list
    varlist =[w for w in frame.columns if w not in var]
    frame = frame[var+varlist]
    return frame 

Se necesitan dos argumentos, el primero es el conjunto de datos, el segundo son las columnas del conjunto de datos que desea traer al frente.

Entonces, en mi caso, tengo un conjunto de datos llamado Frame con variables A1, A2, B1, B2, Total y Date. Si quiero llevar a Total al frente, todo lo que tengo que hacer es:

frame = order(frame,['Total'])

Si quiero traer Total y Fecha al frente, lo hago:

frame = order(frame,['Total','Date'])

EDITAR:

Otra forma útil de usar esto es, si tiene una tabla desconocida y está buscando variables con un término particular en ellas, como VAR1, VAR2, ... puede ejecutar algo como:

frame = order(frame,[v for v in frame.columns if "VAR" in v])
17

Simplemente hazlo

df = df[['mean'] + df.columns[:-1].tolist()]
7
  • TypeError: no se puede convertir el objeto 'int' a str implícitamenteparvij 5 de ene. De 2016 a las 11:10
  • podría ser que la API haya cambiado, también puede hacer esto ... order = df.columns.tolist() df['mean'] = df.mean(1) df.columns = ['mean'] + orderNapitupulu Jon 8 de enero de 2016 a las 10:28
  • 1
    Una variación de esto funcionó bien para mí. Con una lista existente headers, que se usó para crear un dictado que luego se usó para crear el DataFrame, llamé df.reindex(columns=headers). El único problema con el que me encontré fue que ya había llamado df.set_index('some header name', inplace=True), por lo que cuando se realizó la reindexación, agregó otra columna nombrada some header nameya que la columna original ahora era el índice. En cuanto a la sintaxis especificada anteriormente, ['mean'] + df.columnsen el intérprete de Python me daIndex(u'meanAddress', u'meanCity', u'meanFirst Name'...hlongmore 20/06/2017 a las 19:41
  • 1
    @hlongmore: no sé que su código anterior es, pero la edición debería funcionar (usando 0.19.2)Napitupulu Jon 21 de junio de 2017 a las 0:56
  • La edición realmente funciona (estoy en 0.20.2). En mi caso, ya tengo las columnas que quiero, así que creo que df.reindex () es lo que realmente debería usar. hlongmore 22/06/2017 a las 17:49
13

Puede reordenar las columnas del marco de datos usando una lista de nombres con:

df = df.filter(list_of_col_names)

12

Puede hacer lo siguiente (tomando prestadas partes de la respuesta de Aman):

cols = df.columns.tolist()
cols.insert(0, cols.pop(-1))

cols
>>>['mean', 0L, 1L, 2L, 3L, 4L]

df = df[cols]
10

Simplemente escriba el nombre de la columna que desea cambiar y configure el índice para la nueva ubicación.

def change_column_order(df, col_name, index):
    cols = df.columns.tolist()
    cols.remove(col_name)
    cols.insert(index, col_name)
    return df[cols]

Para su caso, esto sería así:

df = change_column_order(df, 'mean', 0)
0
9

Mover cualquier columna a cualquier posición:

import pandas as pd
df = pd.DataFrame({"A": [1,2,3], 
                   "B": [2,4,8], 
                   "C": [5,5,5]})

cols = df.columns.tolist()
column_to_move = "C"
new_position = 1

cols.insert(new_position, cols.pop(cols.index(column_to_move)))
df = df[cols]
7

Quería traer dos columnas al frente de un marco de datos donde no sé exactamente los nombres de todas las columnas, porque se generaron a partir de una declaración dinámica antes. Entonces, si se encuentra en la misma situación: para poner delante las columnas cuyo nombre conoce y luego dejar que sigan "todas las demás columnas", se me ocurrió la siguiente solución general:

df = df.reindex_axis(['Col1','Col2'] + list(df.columns.drop(['Col1','Col2'])), axis=1)
7

Aquí hay una forma de mover una columna existente que modificará el marco de datos existente en su lugar.

my_column = df.pop('column name')
df.insert(3, my_column.name, my_column)  # Is in-place
1
  • Este es prácticamente el único enfoque bueno ya que está en su lugar. La mayoría de los demás enfoques no están implementados y, por lo tanto, no son escalables. Asclepius 15 de enero a las 15:41
6

Aquí hay una respuesta muy simple a esto (solo una línea).

Puede hacerlo después de agregar la columna 'n' en su df de la siguiente manera.

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(10, 5))
df['mean'] = df.mean(1)
df
           0           1           2           3           4        mean
0   0.929616    0.316376    0.183919    0.204560    0.567725    0.440439
1   0.595545    0.964515    0.653177    0.748907    0.653570    0.723143
2   0.747715    0.961307    0.008388    0.106444    0.298704    0.424512
3   0.656411    0.809813    0.872176    0.964648    0.723685    0.805347
4   0.642475    0.717454    0.467599    0.325585    0.439645    0.518551
5   0.729689    0.994015    0.676874    0.790823    0.170914    0.672463
6   0.026849    0.800370    0.903723    0.024676    0.491747    0.449473
7   0.526255    0.596366    0.051958    0.895090    0.728266    0.559587
8   0.818350    0.500223    0.810189    0.095969    0.218950    0.488736
9   0.258719    0.468106    0.459373    0.709510    0.178053    0.414752


### here you can add below line and it should work 
# Don't forget the two (()) 'brackets' around columns names.Otherwise, it'll give you an error.

df = df[list(('mean',0, 1, 2,3,4))]
df

        mean           0           1           2           3           4
0   0.440439    0.929616    0.316376    0.183919    0.204560    0.567725
1   0.723143    0.595545    0.964515    0.653177    0.748907    0.653570
2   0.424512    0.747715    0.961307    0.008388    0.106444    0.298704
3   0.805347    0.656411    0.809813    0.872176    0.964648    0.723685
4   0.518551    0.642475    0.717454    0.467599    0.325585    0.439645
5   0.672463    0.729689    0.994015    0.676874    0.790823    0.170914
6   0.449473    0.026849    0.800370    0.903723    0.024676    0.491747
7   0.559587    0.526255    0.596366    0.051958    0.895090    0.728266
8   0.488736    0.818350    0.500223    0.810189    0.095969    0.218950
9   0.414752    0.258719    0.468106    0.459373    0.709510    0.178053

6

Puede usar un conjunto que es una colección desordenada de elementos únicos para mantener el "orden de las otras columnas intacto":

other_columns = list(set(df.columns).difference(["mean"])) #[0, 1, 2, 3, 4]

Luego, puede usar una lambda para mover una columna específica al frente de la siguiente manera:

In [1]: import numpy as np                                                                               

In [2]: import pandas as pd                                                                              

In [3]: df = pd.DataFrame(np.random.rand(10, 5))                                                         

In [4]: df["mean"] = df.mean(1)                                                                          

In [5]: move_col_to_front = lambda df, col: df[[col]+list(set(df.columns).difference([col]))]            

In [6]: move_col_to_front(df, "mean")                                                                    
Out[6]: 
       mean         0         1         2         3         4
0  0.697253  0.600377  0.464852  0.938360  0.945293  0.537384
1  0.609213  0.703387  0.096176  0.971407  0.955666  0.319429
2  0.561261  0.791842  0.302573  0.662365  0.728368  0.321158
3  0.518720  0.710443  0.504060  0.663423  0.208756  0.506916
4  0.616316  0.665932  0.794385  0.163000  0.664265  0.793995
5  0.519757  0.585462  0.653995  0.338893  0.714782  0.305654
6  0.532584  0.434472  0.283501  0.633156  0.317520  0.994271
7  0.640571  0.732680  0.187151  0.937983  0.921097  0.423945
8  0.562447  0.790987  0.200080  0.317812  0.641340  0.862018
9  0.563092  0.811533  0.662709  0.396048  0.596528  0.348642

In [7]: move_col_to_front(df, 2)                                                                         
Out[7]: 
          2         0         1         3         4      mean
0  0.938360  0.600377  0.464852  0.945293  0.537384  0.697253
1  0.971407  0.703387  0.096176  0.955666  0.319429  0.609213
2  0.662365  0.791842  0.302573  0.728368  0.321158  0.561261
3  0.663423  0.710443  0.504060  0.208756  0.506916  0.518720
4  0.163000  0.665932  0.794385  0.664265  0.793995  0.616316
5  0.338893  0.585462  0.653995  0.714782  0.305654  0.519757
6  0.633156  0.434472  0.283501  0.317520  0.994271  0.532584
7  0.937983  0.732680  0.187151  0.921097  0.423945  0.640571
8  0.317812  0.790987  0.200080  0.641340  0.862018  0.562447
9  0.396048  0.811533  0.662709  0.596528  0.348642  0.563092
5

Simplemente voltear ayuda a menudo.

df[df.columns[::-1]]

O simplemente baraja para echar un vistazo.

import random
cols = list(df.columns)
random.shuffle(cols)
df[cols]
4

El método más hacker del libro

df.insert(0, "test", df["mean"])
df = df.drop(columns=["mean"]).rename(columns={"test": "mean"})
4

Una solución bastante sencilla que funcionó para mí es usarla .reindexen df.columns:

df = df[df.columns.reindex(['mean', 0, 1, 2, 3, 4])[0]]
3

Puede usar reindexcuál se puede usar para ambos ejes:

df
#           0         1         2         3         4      mean
# 0  0.943825  0.202490  0.071908  0.452985  0.678397  0.469921
# 1  0.745569  0.103029  0.268984  0.663710  0.037813  0.363821
# 2  0.693016  0.621525  0.031589  0.956703  0.118434  0.484254
# 3  0.284922  0.527293  0.791596  0.243768  0.629102  0.495336
# 4  0.354870  0.113014  0.326395  0.656415  0.172445  0.324628
# 5  0.815584  0.532382  0.195437  0.829670  0.019001  0.478415
# 6  0.944587  0.068690  0.811771  0.006846  0.698785  0.506136
# 7  0.595077  0.437571  0.023520  0.772187  0.862554  0.538182
# 8  0.700771  0.413958  0.097996  0.355228  0.656919  0.444974
# 9  0.263138  0.906283  0.121386  0.624336  0.859904  0.555009

df.reindex(['mean', *range(5)], axis=1)

#        mean         0         1         2         3         4
# 0  0.469921  0.943825  0.202490  0.071908  0.452985  0.678397
# 1  0.363821  0.745569  0.103029  0.268984  0.663710  0.037813
# 2  0.484254  0.693016  0.621525  0.031589  0.956703  0.118434
# 3  0.495336  0.284922  0.527293  0.791596  0.243768  0.629102
# 4  0.324628  0.354870  0.113014  0.326395  0.656415  0.172445
# 5  0.478415  0.815584  0.532382  0.195437  0.829670  0.019001
# 6  0.506136  0.944587  0.068690  0.811771  0.006846  0.698785
# 7  0.538182  0.595077  0.437571  0.023520  0.772187  0.862554
# 8  0.444974  0.700771  0.413958  0.097996  0.355228  0.656919
# 9  0.555009  0.263138  0.906283  0.121386  0.624336  0.859904
3

Un enfoque simple es usar set(), en particular cuando tiene una lista larga de columnas y no desea manejarlas manualmente:

cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]
2
  • 2
    Una advertencia: el orden de las columnas desaparece si lo pones en conjuntopnv 6 de marzo de 2018 a las 5:31
  • ¡Interesante! @ user1930402 He probado el enfoque anterior en varias ocasiones y nunca tuve ningún problema. Volveré a comprobarlo. Shoresh 6 mar. 18 a las 14:50
3

¿Qué tal usar T?

df = df.T.reindex(['mean', 0, 1, 2, 3, 4]).T
2

Creo que la respuesta de @ Aman es la mejor si conoce la ubicación de la otra columna.

Si no conoce la ubicación de mean, pero solo tiene su nombre, no puede recurrir directamente a cols = cols[-1:] + cols[:-1]. Lo siguiente es lo mejor que se me ocurrió:

meanDf = pd.DataFrame(df.pop('mean'))
# now df doesn't contain "mean" anymore. Order of join will move it to left or right:
meanDf.join(df) # has mean as first column
df.join(meanDf) # has mean as last column
2

Me gustó la respuesta de Shoresh para usar la funcionalidad de conjunto para eliminar columnas cuando no conoce la ubicación, sin embargo, esto no funcionó para mi propósito, ya que necesito mantener el orden de columna original (que tiene etiquetas de columna arbitrarias).

Sin embargo, logré que esto funcionara usando IndexedSet del paquete boltons.

También necesitaba volver a agregar varias etiquetas de columna, por lo que, para un caso más general, usé el siguiente código:

from boltons.setutils import IndexedSet
cols = list(IndexedSet(df.columns.tolist()) - set(['mean', 'std']))
cols[0:0] =['mean', 'std']
df = df[cols]

Espero que esto sea útil para cualquiera que busque en este hilo una solución general.

1
  • ¡Estoy un poco sorprendido! Lo uso setpara este propósito con bastante frecuencia y nunca tuve que lidiar con pedidos. Shoresh 2/10/19 a las 22:09