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

880

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?

Timmie
fuente
1
Para obtener una solución generalizada basada en NumPy, consulte Cómo mover una columna en un marco de datos de pandas , solo se supone un nivel de columna, es decir no MultiIndex.
jpp
Después de buscar lo suficiente, obtuve este mejor enlace para columnas que reorganizan múltiples lógicas en términos bastante simples [las columnas reorganizan la lógica de los pandas] [ datasciencemadesimple.com/…
ravibeli

Respuestas:

853

Una manera fácil sería reasignar el marco de datos con una lista de las 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
Un hombre
fuente
17
en caso de que obtenga "no puede concatenar los objetos 'str' y 'list'", asegúrese de que [] el valor str en cols: cols = [cols [7]] + cols [: 7] + cols [8:]
moeabdol
3
@FooBar Eso no es una unión establecida, es una concatenación de dos listas ordenadas.
Aman el
3
@Aman Solo estoy señalando que tu código está en desuso. El manejo de su publicación es a su discreción.
FooBar
2
@FooBar, el tipo de colses list; incluso permite duplicados (que se descartarán cuando se usen en el marco de datos). Estás pensando en Indexobjetos.
alexis
8
Esto implica copiar TODOS los datos, lo cual es altamente ineficiente. Desearía que los pandas tuvieran una manera de hacerlo sin crear una copia.
Konstantin
442

También podrías 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

freddygv
fuente
8
También puede obtener la lista de columnas con la lista (columnas df.)
Jim
8
odf.columns.tolist()
Jim
Para 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
Los nombres de columna serán enteros en 3.x df = df[['mean1', 0, 1, 2, 3]]
prosti
1
No creo que esta sea una buena respuesta, ya que no proporciona código para 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 usar su respuesta para cambiar el orden de las columnas?
Robvh
312

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' sale 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
Fixxxer
fuente
77
¿Hace una copia?
user3226167
21
@NicholasMorley: esta no es la mejor respuesta si tiene, por ejemplo, 1000 columnas en su df.
AGS
1
no parece que estés asignando a lo <df>.columnsque reclamas inicialmente
fanático número uno de Bjorks
8
Esta es la mejor respuesta para un pequeño número de columnas.
Dongkyu Choi
2
Esta es solo una copia de la respuesta anterior de @freddygv. Esa debería ser la respuesta aceptada, no esta.
James Hirschorn
134

Qué tal si:

df.insert(0, 'mean', df.mean(1))

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

Wes McKinney
fuente
35
¿Podría ser esta una función futura a la que agregar pandas? algo así df.move(0,df.mean)?
Jason
Oh hombre, incluso funciona así df_metadata.insert(0,'Db_name',"raw_data")(Código no relevante para este hilo)
Aetos
3
Hermoso. Y también sucede en el lugar.
cucu8
2
Esta es una solución escalable ya que otras soluciones están escribiendo manualmente nombres de columnas.
CKM
Esto funciona para la pregunta del OP, cuando se crea una nueva columna, pero no para mover una columna; intento de mover resultados en*** ValueError: cannot insert mean, already exists
spinup
122

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']) ))
Alvaro Joao
fuente
2
Traté de configurar copy=Falsepero parece que reindex_axistodavía crea una copia.
Konstantin
1
@ Konstantin ¿Puedes crear otra pregunta sobre este tema? Sería mejor tener más contexto
Alvaro Joao
57

Debe 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 usar 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 usar este enfoque para reordenar las columnas en el orden deseado si están presentes en el Marco de datos.

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]
Alejandro
fuente
47
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' ] ]

Solución 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:

Tiempo de CPU: usuario 1.05 ms, sistema: 35 µs, total: 1.08 ms Tiempo de pared: 995 µs

Solución 2 :

Tiempos de CPU: usuario 933 µs, sys: 0 ns, total: 933 µs Tiempo de pared: 800 µs

Solución 3 :

Tiempos de CPU: usuario 0 ns, sys: 1.35 ms, total: 1.35 ms Tiempo de pared: 1.08 ms

Solución 4 :

Tiempo de CPU: usuario 1.23 ms, sistema: 45 µs, total: 1.27 ms Tiempo de pared: 986 µs

Solución 5 :

Tiempos de CPU: usuario 1.09 ms, sys: 19 µs, total: 1.11 ms Tiempo de pared: 949 µs

Solución 6 :

Tiempos de CPU: usuario 955 µs, sistema: 34 µs, total: 989 µs Tiempo de pared: 859 µs

Pygirl
fuente
1
Una respuesta tan hermosa, gracias.
qasimalbaqali
1
la solución 1 es lo que necesitaba ya que tengo demasiadas columnas (53), gracias
ratnesh
@Pygirl, ¿cuál valor muestra el tiempo real consumido? (usuario, sys, tiempo total o tiempo en la pared)
sergzemsk
1
Esta es para mí la mejor respuesta al problema. Tantas soluciones (incluida una que necesitaba) y un enfoque simple. ¡Gracias!
Gustavo Rottgering
1
Solución 6 (sin comprensión de la lista):df = df.iloc[:, [1, 2, 3, 0]]
Dmitriy Work
43

Desde agosto de 2018:

Si los nombres de columna son demasiado largos para escribir, puede especificar el nuevo orden a través de una lista de 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

Y 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 :)

Yuca
fuente
17

Esta función evita que tenga 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 las variables A1, A2, B1, B2, Total y Fecha. Si quiero llevar a Total al frente, todo lo que tengo que hacer es:

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

Si quiero traer Total y Date al frente, entonces 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])
seeiespi
fuente
17

Me encontré con una pregunta similar, y solo quería agregar lo que resolví. 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 el último por su franqueza.

reloj
fuente
66
Esta fue una buena solución, pero reindex_axis quedará en desuso. Utilicé reindex, y funcionó bien.
Jorge
15

Simplemente hazlo

df = df[['mean'] + df.columns[:-1].tolist()]
Napitupulu Jon
fuente
TypeError: No se puede convertir el objeto 'int' a str implícitamente
parvij
podría ser API ha cambiado, también puede hacer esto ... order = df.columns.tolist() df['mean'] = df.mean(1) df.columns = ['mean'] + order
Napitupulu Jon
1
Una variación de esto funcionó bien para mí. Con una lista existente headers, que se usó para crear un dict 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, se agregó otra columna llamada 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
1
@hlongmore: No sé si tu código anterior es, pero la edición debería funcionar (usando 0.19.2)
Napitupulu Jon
La edición sí 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
11

Puede hacer lo siguiente (tomar 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]
otteheng
fuente
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 como:

df = change_column_order(df, 'mean', 0)
ccerhan
fuente
Esto está subestimado
zelusp
8

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]
pomber
fuente
7

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.

erncyp
fuente
5

Aquí hay una manera 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)
Joe Heffer
fuente
5

Esta pregunta se ha respondido antes, pero reindex_axis está en desuso ahora, por lo que sugeriría usar:

df.reindex(sorted(df.columns), axis=1)
dmvianna
fuente
19
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
1
¿Qué pasa si no quieres ordenarlos?
Chankey Pathak
esto devuelve una copia, no funciona en el lugar
spinup
3

¿Qué tal el uso de "T"?

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

@clocker: Su solución fue muy útil para mí, ya que quería traer dos columnas al frente de un marco de datos donde no conozco exactamente los nombres de todas las columnas, porque se generan a partir de una declaración dinámica antes. Por lo tanto, si se encuentra en la misma situación: para traer columnas al frente de las que conoce el nombre y luego dejar que sigan "todas las otras columnas", se me ocurrió la siguiente solución general;

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

set():

Se está utilizando un enfoque simple set(), en particular cuando tiene una larga lista de columnas y no desea manejarlas manualmente:

cols = list(set(df.columns.tolist()) - set(['mean']))
cols.insert(0, 'mean')
df = df[cols]
Shoresh
fuente
2
Una advertencia: el orden de las columnas desaparece si lo pones en juego
pvarma
¡Interesante! @ user1930402 He intentado el enfoque anterior en varias ocasiones y nunca tuve ningún problema. Comprobaré nuevamente de nuevo.
Shoresh
2

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

Sin embargo, conseguí que esto funcionara usando IndexedSet del paquete de boltons.

También necesitaba volver a agregar varias etiquetas de columna, por lo que para un caso más general utilicé 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.

Jamelade
fuente
Estoy un poco sorprendido! Utilizo setpara este propósito con bastante frecuencia y nunca tuve que lidiar con los pedidos.
Shoresh
2

Puede usar reindexcuál puede usarse 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
silgon
fuente
2

Aquí hay una función para hacer esto para cualquier número de columnas.

def mean_first(df):
    ncols = df.shape[1]        # Get the number of columns
    index = list(range(ncols)) # Create an index to reorder the columns
    index.insert(0,ncols)      # This puts the last column at the front
    return(df.assign(mean=df.mean(1)).iloc[:,index]) # new df with last column (mean) first
freeB
fuente
2

Método más hack en el libro

df.insert(0,"test",df["mean"])
df=df.drop(columns=["mean"]).rename(columns={"test":"mean"})
Kaustubh J
fuente
2

Creo que esta función es más sencilla. Solo necesita especificar un subconjunto de columnas al principio o al final o ambos:

def reorder_df_columns(df, start=None, end=None):
    """
        This function reorder columns of a DataFrame.
        It takes columns given in the list `start` and move them to the left.
        Its also takes columns in `end` and move them to the right.
    """
    if start is None:
        start = []
    if end is None:
        end = []
    assert isinstance(start, list) and isinstance(end, list)
    cols = list(df.columns)
    for c in start:
        if c not in cols:
            start.remove(c)
    for c in end:
        if c not in cols or c in start:
            end.remove(c)
    for c in start + end:
        cols.remove(c)
    cols = start + cols + end
    return df[cols]
hayj
fuente
1

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 cols = cols[-1:] + cols[:-1]. Lo siguiente es lo mejor que se me ocurre:

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
FooBar
fuente
1

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]
plhn
fuente
0

La mayoría de las respuestas no se generalizaron lo suficiente y el método pandas reindex_axis es un poco tedioso, por lo tanto, ofrezco una función simple para mover un número arbitrario de columnas a cualquier posición usando un diccionario donde clave = nombre de columna y valor = posición para mover. Si su marco de datos es grande, pase True a 'big_data', entonces la función devolverá la lista de columnas ordenadas. Y podría usar esta lista para cortar sus datos.

def order_column(df, columns, big_data = False):

    """Re-Orders dataFrame column(s)
       Parameters : 
       df      -- dataframe
       columns -- a dictionary:
                  key   = current column position/index or column name
                  value = position to move it to  
       big_data -- boolean 
                  True = returns only the ordered columns as a list
                          the user user can then slice the data using this
                          ordered column
                  False = default - return a copy of the dataframe
    """
    ordered_col = df.columns.tolist()

    for key, value in columns.items():

        ordered_col.remove(key)
        ordered_col.insert(value, key)

    if big_data:

        return ordered_col

    return df[ordered_col]

# e.g.
df = pd.DataFrame({'chicken wings': np.random.rand(10, 1).flatten(), 'taco': np.random.rand(10,1).flatten(),
                          'coffee': np.random.rand(10, 1).flatten()})
df['mean'] = df.mean(1)

df = order_column(df, {'mean': 0, 'coffee':1 })

>>>

salida

col = order_column(df, {'mean': 0, 'coffee':1 }, True)

col
>>>
['mean', 'coffee', 'chicken wings', 'taco']

# you could grab it by doing this

df = df[col]
Escha
fuente
0

Tengo un caso de uso muy específico para reordenar nombres de columnas en pandas. A veces estoy creando una nueva columna en un marco de datos que se basa en una columna existente. Por defecto, los pandas insertarán mi nueva columna al final, pero quiero que la nueva columna se inserte junto a la columna existente de la que deriva.

ingrese la descripción de la imagen aquí

def rearrange_list(input_list, input_item_to_move, input_item_insert_here):
    '''
    Helper function to re-arrange the order of items in a list.
    Useful for moving column in pandas dataframe.

    Inputs:
        input_list - list
        input_item_to_move - item in list to move
        input_item_insert_here - item in list, insert before 

    returns:
        output_list
    '''
    # make copy for output, make sure it's a list
    output_list = list(input_list)

    # index of item to move
    idx_move = output_list.index(input_item_to_move)

    # pop off the item to move
    itm_move = output_list.pop(idx_move)

    # index of item to insert here
    idx_insert = output_list.index(input_item_insert_here)

    # insert item to move into here
    output_list.insert(idx_insert, itm_move)

    return output_list


import pandas as pd

# step 1: create sample dataframe
df = pd.DataFrame({
    'motorcycle': ['motorcycle1', 'motorcycle2', 'motorcycle3'],
    'initial_odometer': [101, 500, 322],
    'final_odometer': [201, 515, 463],
    'other_col_1': ['blah', 'blah', 'blah'],
    'other_col_2': ['blah', 'blah', 'blah']
})
print('Step 1: create sample dataframe')
display(df)
print()

# step 2: add new column that is difference between final and initial
df['change_odometer'] = df['final_odometer']-df['initial_odometer']
print('Step 2: add new column')
display(df)
print()

# step 3: rearrange columns
ls_cols = df.columns
ls_cols = rearrange_list(ls_cols, 'change_odometer', 'final_odometer')
df=df[ls_cols]
print('Step 3: rearrange columns')
display(df)
pk2019
fuente
0

Una solución bastante sencilla que funcionó para mí es usar .reindex en df.columns:

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